Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson開發。html
它是爲了解決企業應用開發的複雜性而建立的。框架的主要優點之一就是其分層架構,分層架構容許使用者選擇使用哪個組件,同時爲 J2EE 應用程序開發提供集成的框架java
dao(JdbcTemplate) service(spring控制事務) web(springmvc)mysql
Spring的核心是控制反轉(IoC)和麪向切面(AOP)。web
簡單來講,Spring是一個分層的JavaSE/EE full-stack 輕量級開源框架。 1)IoC 和DI 2)AOP面試
一句話描述spring:full-stack 輕量級開源框架spring
分層: full-stack,每個層都提供解決方案sql
web層:struts,spring-MVCexpress
service層:spring 事務控制 spring編程
dao層:hibernate,mybatis , jdbcTemplate(spring提供了一個模板對象) --> spring-data設計模式
ssh:struts2+spring+hibernate(之前的瞭解一下)
ssm:spring+springmvc+mybatis(現階段經常使用)
Spring的核心是控制反轉(IoC)和面向切面(AOP)
1. 方便解耦,簡化開發 (高內聚低耦合)
面試題:spring的IoC(控制反轉)底層用到什麼設計模式?-- 靜態工廠模式 2. AOP編程的支持
3. 聲明式事務的支持 (AOP 動態代理)
4. 方便程序的測試
5. 方便集成各類優秀框架 *****
6. 下降JavaEE API的使用難度 EJB
|
核心容器:beans、core、context、expression
dao service 對象的建立 交給spring
4 + 1 : 4個核心(beans、core、context、expression) + 1個依賴(commons-loggins...jar)
1. 提供UserService接口和實現類
2. 得到UserService實現類的實例
以前開發中,直接new一個對象便可。
UsersService service = new UsersServiceImpl();
學習spring以後,將由Spring建立對象實例--> IoC 控制反轉(Inverse of Control)
以後須要實例對象時,從spring工廠(容器)中得到,須要將實現類的全限定名稱配置到xml文件中
把建立對象的過程交給spring來建立,IoC
1. 位置:任意,開發中通常在classpath下(src)
2. 名稱:任意,開發中經常使用applicationContext.xml
不是必須的。
3. 內容:添加schema約束
約束文件位置:spring-framework-XXX.RELEASE\docs\spring-framework-reference\html\ xsd-config.html
<bean id="userService" name="us" class="com.itqf.service.impl.UserServiceImpl"></bean> |
//建立ApplicationContext對象 ApplicationContext aContext=new ClassPathXmlApplicationContext("applicationContext.xml");
//根據spring的核心對象解析applicationContext.xml配置文件 從配置文件中獲取一個UserService 對象 //從spring的配置文件中獲取對象的三種方式 //方式一:根據對象的class UserService userService = aContext.getBean(UserService.class); //單詞寫錯:NoSuchBeanDefinitionException: No bean named 'userService11' available UserService userService2 = (UserService) aContext.getBean("userService"); UserService userService3 = (UserService) aContext.getBean("us");
System.out.println(userService==userService2); |
1. DI Dependency Injection ,依賴注入
類與類之間的依賴關係,由spring經過spring注入 ---依賴注入
class B {
private A a = new A(); //B類依賴A類 Service依賴dao
}
依賴:一個對象須要使用另外一個對象
注入:經過setter方法(或其餘方式)進行另外一個對象實例設置。
class B {
private A a ;//B類依賴A類 Service依賴dao
}
a對象由spring經過setter方法注入
2. 例如:練習
class BookServiceImpl{
//以前開發:接口 = 實現類 (service和dao耦合)
//private BookDao bookDao = new BookDaoImpl();
//spring以後 (解耦:service實現類使用dao接口,不知道具體的實現類)
private BookDao bookDao;
setter方法
}
模擬spring執行過程
建立service實例:BookService bookService = new BookServiceImpl() -->IoC <bean>
建立dao實例:BookDao bookDao = new BookDaoImple() -->IoC
將dao設置給service:bookService.setBookDao(bookDao); -->DI <property
IoC:把建立對象的過程交給了Spring (<bean ………………>)
DI:經過調用setXXX方法注入另外的對象 <property name=」」 ref=」」>
<!-- 1.dao 等價於: BookDao bookDao = new BookDaoImpl(); --> <bean id="bookDao" class="com.itqf.di.dao.impl.BookDaoImpl"></bean>
<!-- service 等價於: BookService bookService = new BookServiceImpl(); bookService.setBookDao(bookDao); --> <bean id="bookService" class="com.itqf.di.service.impl.BookServiceImpl"> <!-- 注入dao --> <property name="bookDao" ref="bookDao" ></property> </bean> |
1. 步驟一:肯定xsd文件位置
spring-framework-RELEASE\schema\beans
2. 步驟二:複製路徑
3. 步驟三:搜索「xml catalog」
4. 步驟四:添加約束提示
1. api總體瞭解,以後不使用,在學習過程須要。
2. BeanFactory :這是一個工廠,用於生成任意bean。 建立對象
採起延遲加載,第一次getBean時纔會初始化Bean
3. ApplicationContext:是BeanFactory的子接口,功能更強大。當配置文件被加載,就進行對象實例化。
ClassPathXmlApplicationContext 用於加載classpath(類路徑、src)下的xml
加載xml運行時位置 --> /WEB-INF/classes/...xml
FileSystemXmlApplicationContext 用於加載指定盤符下的xml
加載xml運行時位置 --> /WEB-INF/...xml
經過java web ServletContext.getRealPath() 得到具體盤符
BeanFactory
FactoryBean 區別?
l 3種bean實例化方式:默認構造、靜態工廠、實例工廠
<bean id="" class=""> 必須提供默認構造 |
1. 經常使用與spring整合其餘框架(工具)
2. 靜態工廠:用於生成實例對象,全部的方法必須是static
<bean id="" class="工廠全限定類名" factory-method="靜態方法"> |
編寫靜態工廠類
<bean id="userServiceId" class="工廠類對象全路徑 " factory-method="createService"></bean>
1. 實例工廠:必須先有工廠實例對象,經過實例對象建立對象。提供全部的方法都是「非靜態」的
普通的工廠類 (非靜態方法).
<!-- 建立工廠實例 --> <bean id="myBeanFactoryId" class="工廠對象全路徑 "></bean> <!-- 得到userservice * factory-bean 肯定工廠實例 * factory-method 肯定普通方法 --> <bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>
|
做用域:用於肯定spring建立bean實例個數
servlet:單例
struts2:action(處理請求):多例
面試題: struts2是線程安全仍是不安全的?
安全的。
spring:bean:默認是單例
bean標籤有scope屬性能夠設置bean的做用域。
取值:
singleton 單例,默認值。
prototype 多例,每執行一次getBean將得到一個實例。例如:struts整合spring,配置action多例。
面試題: 何時bean的做用域須要設計爲多例的?
Ssh整合(或者struts2和spring整合時),action的建立交給spring建立,須要給bean設計爲多例的。
配置信息
<bean id="" class="" scope=""> |
l 目標方法執行先後執行後,將進行初始化或銷燬。
<bean id="" class="" init-method="初始化方法名稱" destroy-method="銷燬的方法名稱"> |
<bean id="userDao" name="userDao2" class="com.itqf.lifecycle.UserDao" init-method="init" destroy-method="destory"></bean> |
依賴注入方式:手動裝配 和 自動裝配
手動裝配:通常進行配置信息都採用手動
基於xml裝配:構造方法、setter方法 、 p標籤注入
基於註解裝配:@autowrired @resource
自動裝配:
autowire="byName"
byType:按類型裝配
byName:按名稱裝配
constructor構造裝配,
auto: 不肯定裝配。
<constructor-arg> 用於配置構造方法一個參數argument
name :參數的名稱
value:設置普通數據
ref:引用數據,通常是另外一個bean id值
index :參數的索引號,從0開始 。若是隻有索引,匹配到了多個構造方法時,默認使用第一個。
type :肯定參數類型
例如1:使用名稱name
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
例如2:【類型type 和 索引 index】
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
普通數據
<property name="" value="值"> 等效 <property name=""> <value>值</value>
|
引用數據
<property name="" ref="另外一個bean"> 等效 <property name=""> <ref bean="另外一個bean"/>
|
對「setter方法注入」進行簡化,替換<property name="屬性名">,而是在
<bean p:屬性名="普通值" p:屬性名-ref="引用值">
p命名空間使用前提,必須添加命名空間
<bean id="userService" class="com.itqf.bean.p.UserServiceImpl" p:userDao-ref="userDao" > </bean> <bean scope="prototype" id="userAction" class="com.itqf.bean.p.UserAction" p:userService-ref="userService"></bean>
|
<bean id="myCollection" class="com.itqf.bean.collection.MyCollection" autowire="default"> <property name="name" value="天線寶寶"></property> <!-- 數組 --> <property name="arr"> <array> <value>張三</value> <value>lisi</value> <value>王蘇</value> </array> </property> <!-- 集合 --> <property name="list"> <list> <value>basketball</value> <value>football</value> <value>pingpongball</value> </list> </property> <!-- set --> <property name="set"> <set> <value>寶馬</value> <value>勞斯萊斯</value> <value>法拉利</value> <value>賓利</value> <value>QQ</value> </set> </property>
<!-- Map --> <property name="map"> <map> <entry> <key><value>1001</value></key> <value>張三</value> </entry> <entry> <key><value>1002</value></key> <value>李四</value> </entry> <entry> <key><value>1003</value></key> <value>趙六</value> </entry> </map> </property>
<!-- properties 類型 --> <property name="properties"> <props> <prop key="jdbc.driverClass">com.mysql.jdbc.Driver</prop> <prop key="jdbc.url">jdbc:mysql://localhost:3306/book</prop> </props> </property>
</bean>
|
面試題:請說出spring經常使用的註解有哪些?
註解:就是一個類,使用@註解名稱
開發中:使用註解 取代 xml配置文件。
1. @Component取代<bean class="">
@Component("id") 取代 <bean id="" class="">
2.web開發,提供3個@Component註解衍生註解(功能同樣)取代<bean class="">
@Repository :dao層
@Service:service層
@Controller:web層
3.依賴注入,給私有字段設置,也能夠給setter方法設置
引用值:
方式1:按照【類型】注入
@Autowired
private BookDao bookDao;
方式2:按照【名稱】注入2
@Resource( name="名稱")
eg:
@Resource( name="bookDao")
private BookDao bookDao; spring容器中找name爲bookDao
方式3:按照類型注入(autowired)時,若是有兩個匹配結果,會報錯
可使用以下解決方案:
@Qualifier("userServiceImpl2")
//@Autowired //按照類型注入 可是,若是找到多個匹配的就會報錯,expected single matching bean but found 2 //@Qualifier("userServiceImpl2") //按照名稱注入 |
注意:@Qualifier不能當獨使用,通常配合autowired使用
//@Autowired 按照類型注入 //@Qualifier("userServiceImpl") //按照名稱注入 @Resource(name="userServiceImpl") //按照名稱注入 private UserService userService; |
//注入dao @Autowired //按照類型注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; } |
建立對象:
四個:
@Componet
@Repository dao
@Service service
@Controller 控制層
注入:
@Autowired 按照類型注入 (spring提供)
@Qulifer() 配合Autowired 使用(用的少)
@Resource() 按照名稱注入 (jdk)
4.生命週期
初始化:@PostConstruct
銷燬: @PreDestroy
5.做用域 (類前)
@Scope("prototype") 多例
注意:
註解使用前提,導入aop的包,添加命名空間,讓spring掃描含有註解類
spring-aop-4.3.5.RELEASE.jar
在配置文件中添加context標籤:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> |
<!—掃描含有註解的包-->
<context:component-scan base-package="com.qf.annotation"></context:component-scan> |
6. 普通屬性有關的註解
@value 注入屬性值
一、加在成員變量上:經過反射的Field賦值(破壞對象的封裝性)
@Value("慧慧") private String name; |
二、加在set方法上:經過set方法賦值
@Value("tom") public void setName(String name) { this.name = name; } |
@Value直接讀取properties文件中的內容
a1 配置文件
<!-- 掃描properties文件 --> <context:property-placeholder location="classpath:dbinfo.properties"/> <!—掃描一次--> <!-- 掃描帶有註解的包 指定要掃描的包 --> <context:component-scan base-package="com.itqf"></context:component-scan>
|
b1 在類中使用@value註解讀取配置文件中的內容
@value(「${properties配置文件中的key}」)
@Value("${jdbc.driver}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; |
spring整合junit,爲咱們提供了方便的測試方式
一、導包:在spring-02-annotation項目中再加入以下包
spring-test-4.3.5.RELEASE.jar
junit4的包
二、建立測試類
//建立容器 @RunWith(SpringJUnit4ClassRunner.class) //指定建立容器時使用哪一個配置文件 @ContextConfiguration("classpath:applicationContext.xml") public class RunWithTest { //將名爲user的對象注入到u變量中 @Resource(name="person") private Person p; @Test public void testCreatePerson(){ System.out.println(p); } } |
IoC:控制反轉 ,把對象的建立反轉給spring來建立。
底層:靜態工廠
DI:依賴注入,把類與類之間的依賴關係,交給spring注入。
功能:減小耦合度
建立對象三種方式:
bean中
inti-method
distory-method
bean的做用域
scope=」singleton」 默認 單例
prototype 多例
注入:
構造器注入
setter
p標籤注入