目錄
一、Spring框架概述
二靴姿、Sping 初體驗
三沃但、IOC容器
?1. IOC概念和原理
?2. IOC接口(BeanFactory)
?3. Bean管理什么是Bean管理?
??IOC操作Bean管理(基于xml)
??IOC操作Bean管理(基于注解)
?4. Bean的作用域
?5. Bean的生命周期
?6. 引入外部屬性文件
一佛吓、Spring框架概述
- Spring 是輕量級的開源JavaEE 框架
- Spring 可以解決企業(yè)應用開發(fā)的復雜性
- Spring 的兩個核心部分:IOC 和 AOP
- IOC: 控制反轉(zhuǎn)宵晚,把創(chuàng)建對象的過程交給Spring 進行管理
- AOP: 面向切面,不修改源代碼進行功能增強
- Spring 特點
- 方便解耦辈毯,簡化開發(fā)
- AOP編程支持
- 方便程序測試
- 方便和其他框架進行整和
- 方便進行事務操作
- 降低API開發(fā)難度
二坝疼、Sping 初體驗
創(chuàng)建一個maven項目
-
引入spring5.x版本基礎jar包
core搜贤、context谆沃、aop、expression (commons-logging 非Spring框架內(nèi))
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.2.9.RELEASE</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>
-
創(chuàng)建一個普通類仪芒,在這個類創(chuàng)建普通方法
public class User { public void add() { System.out.println("add..."); } }
-
創(chuàng)建Spring配置文件唁影,在配置文件配置創(chuàng)建的對象
- Spring配置文件使用xml
- 創(chuàng)建bean1.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <!--配置User對象創(chuàng)建--> <bean id="user" class="com.yang.spring5.User"></bean> </beans>
-
進行測試編碼
public class Spring5Test { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2 獲取配置創(chuàng)建的對象 User user = context.getBean("user", User.class); System.out.println(user); user.add(); } }
三、IOC容器
1. IOC概念和原理
- 什么是IOC ?
控制反轉(zhuǎn)掂名,把對象創(chuàng)建和對象之間的調(diào)用過程据沈,交給spring管理
使用IOC的目的:為了降低耦合度
- IOC底層原理
主要使用了xml解析、工廠模式饺蔑、反射
-
IOC過程
- 第一步 xml配置文件锌介,配置要創(chuàng)建的對象
<!--配置User對象創(chuàng)建--> <bean id="user" class="com.yang.spring5.User"></bean>
- 第二步 創(chuàng)建工廠類,通過xml解析猾警,獲取class屬性值孔祸,再通過反射創(chuàng)建對象
2. IOC接口(BeanFactory)
IOC思想是基于IOC容器完成的,IOC容器的底層就是對象工廠
-
Spring提供IOC容器實現(xiàn)的兩種方式
- BeanFactory:IOC容器基本實現(xiàn)发皿,Spring內(nèi)部使用接口崔慧,不提供開發(fā)人員使用
加載配置文件的時候不會創(chuàng)建對象,獲取對象的時候才會去創(chuàng)建對象
- ApplicationCpntext:BeanFactory的子接口穴墅,功能更加強大惶室,一般由開發(fā)人員使用
加載配置文件的時候就會把配置文件中的對象進行創(chuàng)建
加載配置文件的兩個實現(xiàn)類 - ClassPathXmlApplicationContext - FileSystemXmlApplicationContext 這兩個實現(xiàn)類的區(qū)別 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");//類路徑 ApplicationContext context = new FileSystemXmlApplicationContext("D:\\Java_learning\\spring-learning\\src\\main\\resources\\bean1.xml");//絕對路徑
3. Bean管理
什么是Bean管理温自?
Bean管理實際上是指兩個操作
- Spring創(chuàng)建對象
- Spring注入屬性
IOC操作Bean管理(基于xml)
-
在Spring配置文件中,使用bean標簽皇钞,標簽里添加對應屬性悼泌,就可以實現(xiàn)對象創(chuàng)建。
<!--配置User對象創(chuàng)建-->
<bean id="user" class="com.yang.spring5.User"></bean>
-
bean標簽中常用屬性
- id:唯一標識
- class:類全路徑
- name:類似與id屬性夹界,區(qū)別是name可以加特殊標識券躁,如 “/” 等。
-
創(chuàng)建對象的時候掉盅,默認執(zhí)行無參構(gòu)造方法也拜,完成對象創(chuàng)建。
-
屬性注入(DI)
set注入趾痘、構(gòu)造器注入慢哈、P名稱空間注入
- 第一種:使用set方法注入。
- 創(chuàng)建類永票,定義屬性和它的set方法
/** * @Author: csy * @Date: 2020/12/17 20:38 * @Description: 使用set方法進行屬性注入 */ public class Book { private String name; public void setName(String name) { this.name = name; } public void show() { System.out.println("name:" + name); } }
- 在spring配置文件中卵贱,配置對象創(chuàng)建和屬性注入
<!--配置Book對象創(chuàng)建--> <bean id="book" class="com.yang.spring5.Book"> <!--使用property完成屬性注入--> <property name="name" value="語文"></property> </bean>
- 測試
public class Spring5Test { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2 獲取配置創(chuàng)建的對象 Book book = context.getBean("book", Book.class); book.show(); } }
- 輸出
name:語文
- 第二種:使用有參構(gòu)造方法注入。
- 創(chuàng)建類侣集,定義屬性和有參構(gòu)造方法键俱。
/** * @Author: csy * @Date: 2020/12/17 21:15 * @Description: 使用有參構(gòu)造方法注入 */ public class Orders { private String name; public Orders(String name) { this.name = name; } public void show(){ System.out.println("name:"+ name); } }
- 在Spring配置文件中,配置對象創(chuàng)建和屬性注入
<!--配置Orders對象創(chuàng)建--> <bean id="orders" class="com.yang.spring5.Orders"> <!--使用 constructor-arg 完成屬性注入--> <constructor-arg name="name" value="銷售訂單"/> </bean>
- 測試
public class Spring5Test { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2 獲取配置創(chuàng)建的對象 Orders orders = context.getBean("orders", Orders.class); orders.show(); } }
- 結(jié)果
name:銷售訂單
-
第三種:P名稱空間注入
使用P名稱空間注入世分,可以簡化基于XML配置方式
- 在配置文件中添加P名稱空間
xmlns:p="http://www.springframework.org/schema/p"
- 配置對象創(chuàng)建和屬性注入
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--使用P標簽注入--> <bean id="book" class="com.yang.spring5.Book" p:name="數(shù)學"> </bean> </beans>
-
特殊類型值注入
- null
<!--通過<null></null>標簽注入--> <!--配置Book對象創(chuàng)建--> <bean id="book" class="com.yang.spring5.Book"> <!--使用property完成屬性注入--> <property name="name"> <null></null> </property> </bean>
- 特殊符號
<!--1.把特殊符號轉(zhuǎn)義--> <!--2.把帶特殊符號的內(nèi)容寫到CDATA中--> <!--配置Book對象創(chuàng)建--> <bean id="book" class="com.yang.spring5.Book"> <!--使用property完成屬性注入--> <property name="name"> <value><![CDATA[<<語文>>]]></value> </property> </bean>
-
注入屬性-外部bean
場景:service類中引用dao類
代碼示例:
- 創(chuàng)建兩個類编振,service類和dao類
- 在service類中調(diào)用dao里的方法
- 在spring配置文件中進行配置
public class UserService { /** * 創(chuàng)建UserDao類型屬性,生成set方法 */ private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add() { System.out.println("service add...."); userDao.update(); } }
public interface UserDao { public void update(); }
public class UserDaoImpl implements UserDao { @Override public void update() { System.out.println("dao update...."); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean id="userService" class="com.yang.spring5.service.UserService"> <!-- 注入userDao對象 --> <!-- name屬性:類里的屬性名稱 --> <!-- ref屬性:創(chuàng)建userDao對象bean標簽id值 --> <property name="userDao" ref="userDao"></property> </bean> <bean id="userDao" class="com.yang.spring5.dao.UserDaoImpl"></bean> </beans>
public class Spring5Test2 { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); //2 獲取配置創(chuàng)建的對象 UserService userService = context.getBean("userService", UserService.class); userService.add(); } }
-
注入屬性-內(nèi)部bean和級聯(lián)賦值
內(nèi)部bean
場景:員工和部門(一對多關系)
一個部門有多個員工臭埋,一個員工屬于一個部門
部門是一踪央,員工是多
代碼實例:
- 創(chuàng)建員工類與部門類(員工類中有部門屬性)
- xml配置文件中進行內(nèi)部bean配置
package com.yang.spring5.bean; /** * @Description: 部門 * @author: caoshenyang * @date: 2020.12.31 */ public class Dept { private String name; public void setName(String name) { this.name = name; } @Override public String toString() { return "Dept{" + "name='" + name + '\'' + '}'; } }
package com.yang.spring5.bean; /** * @Description: 員工 * @author: caoshenyang * @date: 2020.12.31 */ public class Emp { private String name; private String gender; private Dept dept; public void setName(String name) { this.name = name; } public void setGender(String gender) { this.gender = gender; } public void setDept(Dept dept) { this.dept = dept; } @Override public String toString() { return "Emp{" + "name='" + name + '\'' + ", gender='" + gender + '\'' + ", dept=" + dept + '}'; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean name="emp" class="com.yang.spring5.bean.Emp"> <property name="name" value="張三"></property> <property name="gender" value="男"></property> <!--內(nèi)部bean注入--> <!--當然也可以采用外部bean的方式來實現(xiàn) 1.外部創(chuàng)建dept的bean 2.內(nèi)部通過ref標簽引用--> <property name="dept" > <bean id="dept" class="com.yang.spring5.bean.Dept"> <property name="name" value="IT部門"></property> </bean> </property> </bean> </beans>
package com.yang.spring5.testdemo; import com.yang.spring5.bean.Emp; import com.yang.spring5.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author: csy * @Date: 2020/12/28 22:16 * @Description: */ public class Spring5Test3 { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); //2 獲取配置創(chuàng)建的對象 Emp emp = context.getBean("emp", Emp.class); System.out.println(emp); } }
輸出:
Emp{name='張三', gender='男', dept=Dept{name='IT部門'}}
級聯(lián)賦值
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean name="emp" class="com.yang.spring5.bean.Emp"> <property name="name" value="張三"></property> <property name="gender" value="男"></property> <!--內(nèi)部bean注入--> <!--當然也可以采用外部bean的方式來實現(xiàn) 1.外部創(chuàng)建dept的bean 2.內(nèi)部通過ref標簽引用--> <property name="dept" ref="dept" > </property> <!--依賴于get方法獲取dept對象,然后給dept對象屬性賦值瓢阴,所以在Emp對象中需要實現(xiàn)對應的get方法--> <property name="dept.name" value="財務部門"></property> </bean> <bean id="dept" class="com.yang.spring5.bean.Dept"></bean> </beans>
package com.yang.spring5.testdemo; import com.yang.spring5.bean.Emp; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author: csy * @Date: 2020/12/28 22:16 * @Description: */ public class Spring5Test4 { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); //2 獲取配置創(chuàng)建的對象 Emp emp = context.getBean("emp", Emp.class); System.out.println(emp); } }
輸出:
Emp{name='張三', gender='男', dept=Dept{name='財務部門'}
-
注入集合屬性
- 注入數(shù)組類型屬性
- 注入List集合屬性
- 注入Map集合屬性
- 注入Set集合屬性
場景:當我們需要注入集合類型屬性值的時候
代碼示例:
- 創(chuàng)建Stu類
- xml配置
package com.yang.spring5.bean; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; /** * @Description: 學生 * @author: caoshenyang * @date: 2020.12.31 */ public class Student { private String[] course; private List<String> lists; private Map<String, String> maps; private Set<String> sets; public void setCourse(String[] course) { this.course = course; } public void setLists(List<String> lists) { this.lists = lists; } public void setMaps(Map<String, String> maps) { this.maps = maps; } public void setSets(Set<String> sets) { this.sets = sets; } @Override public String toString() { return "Student{" + "course=" + Arrays.toString(course) + ", lists=" + lists + ", maps=" + maps + ", sets=" + sets + '}'; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean name="student" class="com.yang.spring5.bean.Student"> <property name="course"> <array> <value>語文</value> <value>數(shù)學</value> </array> </property> <property name="lists"> <list> <value>JAVA</value> <value>C語言</value> </list> </property> <property name="maps"> <map> <entry key="1" value="MySql"/> <entry key="2" value="Redis"/> </map> </property> <property name="sets"> <set> <value>C++</value> <value>C#</value> </set> </property> </bean> </beans>
輸出:
Student{course=[語文, 數(shù)學], lists=[JAVA, C語言], maps={1=MySql, 2=Redis}, sets=[C++, C#]}
-
在集合里設置對象類型值
場景:教師類的課程屬性為課程類
- 創(chuàng)建2個類Teacher類和Course類
- xml配置
代碼示例:
package com.yang.spring5.bean; import java.util.List; /** * @Description: 教師 * @author: caoshenyang * @date: 2020.12.31 */ public class Teacher { private List<Course> courses; public void setCourses(List<Course> courses) { this.courses = courses; } @Override public String toString() { return "Teacher{" + "courses=" + courses + '}'; } }
package com.yang.spring5.bean; /** * @Description: 課程 * @author: caoshenyang * @date: 2020.12.31 */ public class Course { private String name; public void setName(String name) { this.name = name; } @Override public String toString() { return "Course{" + "name='" + name + '\'' + '}'; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean name="teacher" class="com.yang.spring5.bean.Teacher"> <property name="courses"> <list> <ref bean="course1"/> <ref bean="course2"/> </list> </property> </bean> <bean name="course1" class="com.yang.spring5.bean.Course"> <property name="name" value="JAVA"/> </bean> <bean name="course2" class="com.yang.spring5.bean.Course"> <property name="name" value="VUE"/> </bean> </beans>
輸出:
Teacher{courses=[Course{name='JAVA'}, Course{name='VUE'}]}
-
把集合注入部分提取出來
- spring配置文件中引入名稱空間util
- 使用util標簽完成list集合注入提取
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <util:list id="courses"> <ref bean="course1"/> <ref bean="course2"/> </util:list> <bean name="teacher" class="com.yang.spring5.bean.Teacher"> <property name="courses" ref="courses"/> </bean> <bean name="course1" class="com.yang.spring5.bean.Course"> <property name="name" value="JAVA"/> </bean> <bean name="course2" class="com.yang.spring5.bean.Course"> <property name="name" value="VUE"/> </bean> </beans>
輸出:
Teacher{courses=[Course{name='JAVA'}, Course{name='VUE'}]}
-
FactoryBean
- 普通bean:xml中定義什么類型的bean畅蹂,即返回什么類型的bean
前面介紹的都為普通bean
- 工廠bean:xml中定義的類型可以和返回的類型不一樣
代碼示例:
- 創(chuàng)建工廠類,實現(xiàn)FactoryBean接口
- 實現(xiàn)接口中的方法荣恐,在方法中定義返回的類型
package com.yang.spring5.factoryBean; import com.yang.spring5.bean.Course; import org.springframework.beans.factory.FactoryBean; /** * @Description: 工廠bean * @author: caoshenyang * @date: 2020.12.31 */ public class MyFactoryBean implements FactoryBean<Course> { @Override public Course getObject() throws Exception { Course course = new Course(); course.setName("JAVA"); return course; } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean name="myFactoryBean" class="com.yang.spring5.factoryBean.MyFactoryBean"></bean> </beans>
package com.yang.spring5.testdemo; import com.yang.spring5.bean.Course; import com.yang.spring5.bean.Teacher; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author: csy * @Date: 2020/12/28 22:16 * @Description: */ public class Spring5Test8 { @Test public void testAdd() { //1 加載spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean8.xml"); //2 獲取配置創(chuàng)建的對象 Course course = context.getBean("myFactoryBean", Course.class); System.out.println(course); } }
輸出:
Course{name='JAVA'}
IOC操作Bean管理(基于注解)
什么是注解
(1)注解是代碼特殊標記液斜,格式:@注解名稱(屬性名稱=屬性值, 屬性名稱=屬性值…)
(2)使用注解,注解作用在類上面叠穆,方法上面少漆,屬性上面
(3)使用注解目的:簡化 xml 配置
Spring針對Bean管理提供的注解(下面四個注解功能一樣,都可以用來創(chuàng)建實例)
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
基于注解方式實現(xiàn)對象創(chuàng)建
(1)引入AOP依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.9.RELEASE</version> </dependency>
(2)開啟注解掃描
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 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"> <!--開啟注解掃描 1.掃描多個包痹束,多個包使用逗號隔開 2.掃描包的上層目錄 --> <context:component-scan base-package="com.yang.spring5"></context:component-scan> </beans>
(3)創(chuàng)建類检疫,加上注解
//在注解里面 value 屬性值可以省略不寫, //默認值是類名稱祷嘶,首字母小寫 //StudentService -- studentService @Service(value = "studentService") //注解等同于XML配置文件:<bean id="studentService" class=".."/> public class StudentService { public void show() { System.out.println("service show ......"); } }
測試:
@Test public void testAdd() { //1 加載spring配置文件 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean12.xml"); //2 獲取配置創(chuàng)建的對象 StudentService studentService = context.getBean("studentService", StudentService.class); studentService.show(); }
輸出:
service show ......
開啟組件掃描細節(jié)配置
<!--示例 1 use-default-filters="false" 表示現(xiàn)在不使用默認 filter屎媳,自己配置 filter context:include-filter 夺溢,設置掃描哪些內(nèi)容 --> <context:component-scan base-package="com.yang.spring5" use-default-filters="false"> <!--代表只掃描Controller注解的類--> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--示例 2 下面配置掃描包所有內(nèi)容 context:exclude-filter: 設置哪些內(nèi)容不進行掃描 --> <context:component-scan base-package="com.yang.spring5"> <!--表示Controller注解的類之外一切都進行掃描--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
基于注解方式實現(xiàn)屬性注入
(1)@AutoWired:根據(jù)屬性類型進行自動裝配
? 第一步 把 service 和 dao 對象創(chuàng)建矛洞,在 service 和 dao 類添加創(chuàng)建對象注解
? 第二步 在 service 注入 dao 對象床未,在 service 類添加 dao 類型屬性,在屬性上面使用注解
@Service public class UserService { //定義 dao 類型屬性 //不需要添加 set 方法 //添加注入屬性注解 @Autowired private UserDao userDao; public void add() { System.out.println("service add......."); userDao.add(); } } //Dao實現(xiàn)類 @Repository public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("dao add....."); } }
(2)@Qualifier:根據(jù)屬性名稱進行注入羡亩,這個@Qualifier 注解的使用丹禀,和上面@Autowired 一起使用
@Autowired //根據(jù)名稱進行注入(目的在于區(qū)別同一接口下有多個實現(xiàn)類状勤,根據(jù)類型就無法選擇,從而出錯K帷) @Qualifier(value = "userDaoImpl1") private UserDao userDao;
(3)@Resource:可以根據(jù)類型注入持搜,也可以根據(jù)名稱注入
//@Resource //根據(jù)類型進行注入 @Resource(name = "userDaoImpl1") //根據(jù)名稱進行注入 private UserDao userDao;
(4)@Value:普通類型值注入
@Value(value = "abc") private String name
完全注解開發(fā)
(1)創(chuàng)建配置類,替換xml配置文件
@Configuration //作為配置類焙矛,替代 xml 配置文件 @ComponentScan(basePackages = {"com.yang.spring5"}) public class SpringConfig { }
(2)編寫測試類
@Test public void testService2() { //加載配置類 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); }
4. Bean的作用域
bean作用域是用來確定從Spring容器中返回哪種類型的bean實例給調(diào)用者葫盼。
spring里配置的bean是單例還是多實例的?
默認為單例村斟,可進行配置 使用 scope 標簽贫导, prototype 多實例 、 singleton 單例 (默認)
<--多實例--> <bean id="user" class="com.yang.spring5.User" scope="prototype"></bean> <--單例--> <bean id="user" class="com.yang.spring5.User" scope="singleton "></bean>
scope設置prototype 和singleton 的區(qū)別蟆盹?
- singleton 單例 prototype 多實例
- singleton bean在配置加載的時候進行創(chuàng)建孩灯,prototype bean在調(diào)用getBean方法的時候創(chuàng)建
5. Bean的生命周期
從對象創(chuàng)建到對象銷毀的過程(5步)
通過構(gòu)造器創(chuàng)建 bean 實例(無參數(shù)構(gòu)造)
為 bean 的屬性設置值和對其他 bean 引用(調(diào)用 set 方法)
調(diào)用 bean 的初始化的方法(需要進行配置初始化的方法,調(diào)用init方法)
bean 可以使用了(對象獲取到了逾滥,調(diào)用getBean方法)
當容器關閉時候峰档,調(diào)用 bean 的銷毀的方法(需要進行配置銷毀的方法,調(diào)用destroy方法)
代碼示例
package com.yang.spring5.bean; /** * @Description: 訂單 * @author: caoshenyang * @date: 2021.01.04 */ public class Order { private String name; public Order() { System.out.println("第一步 執(zhí)行無參構(gòu)造方法創(chuàng)建 bean 實例"); } public void setName(String name) { this.name = name; System.out.println("第二步 調(diào)用setter方法設置屬性值"); } public void initMethod(){ System.out.println("第三步 執(zhí)行初始化方法"); } public void destroyMethod(){ System.out.println("第五步 執(zhí)行銷毀方法"); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean id="order" class="com.yang.spring5.bean.Order" init-method="initMethod" destroy-method="destroyMethod"> <property name="name" value="手機"/> </bean> </beans>
@Test public void testAdd() { //1 加載spring配置文件 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean9.xml"); //2 獲取配置創(chuàng)建的對象 Order order = context.getBean("order", Order.class); System.out.println("第四步 獲取創(chuàng)建bean實例對象"); System.out.println(order); context.close(); }
輸出:
第一步 執(zhí)行無參構(gòu)造方法創(chuàng)建 bean 實例 第二步 調(diào)用setter方法設置屬性值 第三步 執(zhí)行初始化方法 第四步 獲取創(chuàng)建bean實例對象 com.yang.spring5.bean.Order@ed9d034 第五步 執(zhí)行銷毀方法
添加bean的后置處理器(bean的生命周期為7步)
- 創(chuàng)建后置處理器類匣距,需要實現(xiàn)BeanPostProcessor接口
- 配置后置處理器
package com.yang.spring5.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * @Description: 后置處理器 * @author: caoshenyang * @date: 2021.01.04 */ public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之前執(zhí)行的方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之后執(zhí)行的方法"); return bean; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean id="order" class="com.yang.spring5.bean.Order" init-method="initMethod" destroy-method="destroyMethod"> <property name="name" value="手機"/> </bean> <!--配置后置處理器--> <bean id="myBeanPostProcessor" class="com.yang.spring5.bean.MyBeanPostProcessor"></bean> </beans>
@Test public void testAdd() { //1 加載spring配置文件 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean9.xml"); //2 獲取配置創(chuàng)建的對象 Order order = context.getBean("order", Order.class); System.out.println("第四步 獲取創(chuàng)建bean實例對象"); System.out.println(order); context.close(); }
輸出:
第一步 執(zhí)行無參構(gòu)造方法創(chuàng)建 bean 實例 第二步 調(diào)用setter方法設置屬性值 在初始化之前執(zhí)行的方法 第三步 執(zhí)行初始化方法 在初始化之后執(zhí)行的方法 第四步 獲取創(chuàng)建bean實例對象 com.yang.spring5.bean.Order@4eb7f003 第五步 執(zhí)行銷毀方法
6. 引入外部屬性文件
下面以配置數(shù)據(jù)庫連接作為示例面哥。
- 方式一:直接配置數(shù)據(jù)庫信息
- 引入Druid連接池依賴
- 配置連接池
<!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.4</version> </dependency>
<!--直接配置連接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>
- 方式二:引入外部屬性文件配置數(shù)據(jù)庫連接池
- 創(chuàng)建外部屬性文件,properties類型文件(jdbc.properties)
- 寫數(shù)據(jù)庫信息
- 引入到Spring配置文件中
- 設置context名稱空間
- 引入數(shù)據(jù)
prop.driverClass=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/userDb prop.userName=root prop.password=root
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 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:property-placeholder location="classpath:jdbc.properties"/> <!--配置連接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClass}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.userName}"></property> <property name="password" value="${prop.password}"></property> </bean> </beans>