Spring 5 框架【第二节 IOC容器】
- Spring 5 框架
- 一、Spring 简介
- 二、IOC容器
- 三、AOP
- 四、JDBCTemplate
- 五、事务管理
Spring 5 框架
一、Spring 简介
https://blog.csdn.net/ljf190409/article/details/117197937
二、IOC容器
(1)、IOC底层原理
(2)、IOC接口( BeanFactory)
(3)、IOC操作 Bean管理(基于xml)
(4)、IOC操作Bean管理(基于注解)
1、什么是IOC(概念和原理)
1.1、什么是IOC(控制反转)
a)把对象创建和对象之间的调用过程,交给Spring进行管理
b)使用IOC目的:为了降低耦合度
1.2、 IOC底层
a)xml解析、工厂模式、反射
1.3、IOC底层原理过程
2、IOC(接口)
-
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
-
Spring 提供IOC容器实现两种方式:(两个接口)。
a)BeanFactory接口:
-----IOC容器基本实现,是Spring内部接口的使用接口,不提供给开发人员进行使用(加载配置文件时候不会创建对象,在获取对象时才会创建对象。) b)ApplicationContext接口:
-----BeanFactory接口的子接口,提供更多更强大的功能,提供给开发人员使用(加载配置文件时候就会把在配置文件对象进行创建)//1.加载spring配置文件,两种接口 // BeanFactory(父类) / ApplicationContext(子类) ApplicationContext context= new ClassPathXmlApplicationContext("spring5_demo1.xml"); //2.获取配置文件的对象 Main main=context.getBean("main",Main.class);
-
ApplicationContext接口的实现类
3、IOC操作Bean管理
3.1、什么是Bean管理
(1)Bean管理就是两个操作:
(2)Spring创建对象;
(3)Spring注入属性;
3.2、Bean管理操作有两种工作方式
(1)基于xml配置文件方式实现
(2)基于注解方式实现
4、IOC操作Bean管理( 基于xml配置文件方式 )
4.1、基于XML方式创建对象
<!--1.配置文件Main对象的创建-->
<bean id="main" class="com.company.demo1.Main"></bean>
- (1)在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
- (2)在bean标签有很多属性,介绍常用的属性
- id属性:唯一标识
- class属性:类的路径(包类路径)
- (3)创建对象时候,默认也是执行无参数构造方法v
4.2、基于XML方式注入属性
-
DI : 依赖注入,就是注入属性
a : 第一种注入方式:使用set方法
b : 第二种注入方式:有参构造注入
c : p名称空间注入,可以简化基于xml配置方式。(了解)
4.3、第一种注入方式:使用set方法
案例:
/*
*实体类
*/
public class Book {
private String bname;
private String ba;
private String address;
//set方法注入
public void setBname(String bname) {
this.bname = bname;
}
public void setBa(String ba){
this.ba = ba;
}
public void setAddress(String address) {
this.address = address;
}
//输出结果
public void add1(){
System.out.println(bname+"::"+ba+"::"+address);
}
}
<!-- 配置文件-->
<?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">
<!-- 2.set方法注入属性-->
<bean id="book" class="com.company.demo1.Book">
<!-- 使用property完成属性的注入
name:类里面的属性名称
value:向属性注入的值
-->
<property name="bname" value="易筋经"></property>
<property name="ba" value="老子"></property>
<!-- NUll值 -->
<!-- <property name="address">-->
<!-- <null></null>-->
<!-- </property>-->
<!-- 属性值包含特殊符号 value="<<南京>>"
1.把<>进行转义<>
2.把带特殊符号内容写入CDATA
-->
<property name="address">
<value><![CDATA[<<南京>>]]></value>
</property>
</bean>
</beans>
/*
* 测试类
*/
@Test
public void testBook(){
//1.加载spring配置文件,两种接口
// BeanFactory(父类)/ApplicationContext(子类)
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo1.xml");
//2.获取配置文件的对象
Book book= context.getBean("book",Book.class)
System.out.println(book);
book.add1();
}
4.4、第二种注入方式:有参构造注入
案例:
/*
*实体类
*/
package com.company.demo1;
public class Orders {
private String oname;
private String address;
public Orders(String oname, String address) {
this.oname = oname;
this.address = address;
}
public void add(){
System.out.println(oname+"::"+address);
}
}
<!-- 配置文件-->
<!-- 3.有参构造注入属性-->
<bean id="orders" class="com.company.demo1.Orders">
<constructor-arg name="oname" value="abc"></constructor-arg>
<constructor-arg name="address" value="China"></constructor-arg>
</bean>
/*
* 测试类
*/
@Test
public void testOrders(){
//1.加载spring配置文件,两种接口
// BeanFactory(父类)/ApplicationContext(子类)
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo1.xml");
//2.获取配置文件的对象
Orders orders= context.getBean("orders",Orders.class);
System.out.println(orders);
orders.add();
}
4.5、第三种注入方式,p名称空间注入,可以简化基于xml配置方式。(了解)
<!--1、添加p名称空间在配置文件头部-->
<?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" <!--在这里添加一行p-->
<!--2、在bean标签进行属性注入(算是set方式注入的简化操作)-->
<bean id="orders" class="com.company.demo1.Orders" p:oname="abc" p:address="China">
</bean>
5、IOC操作Bean管理( xml方式注入其他类型属性 )
5.1、字面量–NULL值
案例:
/*
*实体类
*/
public class Book {
private String bname;
private String ba;
private String address;
//set方法注入
public void setBname(String bname) {
this.bname = bname;
}
public void setBa(String ba){
this.ba = ba;
}
public void setAddress(String address) {
this.address = address;
}
//输出结果
public void add1(){
System.out.println(bname+"::"+ba+"::"+address);
}
}
<!-- 配置文件-->
<?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">
<!-- 2.set方法注入属性-->
<bean id="book" class="com.company.demo1.Book">
<!-- 使用property完成属性的注入
name:类里面的属性名称
value:向属性注入的值
-->
<property name="bname" value="易筋经"></property>
<property name="ba" value="老子"></property>
<!-- NUll值 -->
<property name="address">
<null></null>
</property>
</bean>
</beans>
/*
* 测试类
*/
@Test
public void testBook(){
//1.加载spring配置文件,两种接口
// BeanFactory(父类)/ApplicationContext(子类)
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo1.xml");
//2.获取配置文件的对象
Book book= context.getBean("book",Book.class)
System.out.println(book);
book.add1();
}
5.2、字面量–属性包含特殊符号
案例:
/*
*实体类
*/
public class Book {
private String bname;
private String ba;
private String address;
//set方法注入
public void setBname(String bname) {
this.bname = bname;
}
public void setBa(String ba){
this.ba = ba;
}
public void setAddress(String address) {
this.address = address;
}
//输出结果
public void add1(){
System.out.println(bname+"::"+ba+"::"+address);
}
}
<!-- 配置文件-->
<?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">
<!-- 2.set方法注入属性-->
<bean id="book" class="com.company.demo1.Book">
<!-- 使用property完成属性的注入
name:类里面的属性名称
value:向属性注入的值
-->
<property name="bname" value="易筋经"></property>
<property name="ba" value="老子"></property>
<!-- 属性值包含特殊符号 value="<<南京>>"
1.把<>进行转义<>
2.把带特殊符号内容写入CDATA
-->
<property name="address">
<value><![CDATA[<<南京>>]]></value>
</property>
</bean>
</beans>
/*
* 测试类
*/
@Test
public void testBook(){
//1.加载spring配置文件,两种接口
// BeanFactory(父类)/ApplicationContext(子类)
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo1.xml");
//2.获取配置文件的对象
Book book= context.getBean("book",Book.class)
System.out.println(book);
book.add1();
}
5.3、注入属性-外部Bean
<!--1 service和dao对象创建-->
<bean id="userService" class="com.company.demo2.service.UserService">
<!--注入userDao对象
name属性:类里面属性名称
ref属性:创建userDao对象bean标签id值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.company.demo2.dao.UserDaoImpl"></bean>
-
创建两个类service类和dao类
-
在service调用dao里面的方法
-
在spring配置文件中进行配置,
案例:
package com.company.demo2.dao;
public interface UserDao {
public void update();
}
package com.company.demo2.dao;
public class UserDaoImpl implements UserDao {
@Override
public void update() {
System.out.println("dao update...........");
}
}
package com.company.demo2.service;
import com.company.demo2.dao.UserDao;
public class UserService {
//创建UserDao类型属性,生成set方法
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add() {
System.out.println("service add...............");
userDao.update();//调用dao方法
}
}
<?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 -->
<!--1 service和dao对象创建-->
<bean id="userService" class="com.company.demo2.service.UserService">
<!--注入userDao对象
name属性:类里面属性名称
ref属性:创建userDao对象bean标签id值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.company.demo2.dao.UserDaoImpl"></bean>
</beans>
@Test
public void testBean1(){
//1.加载spring配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo2.xml");
//2.获取配置创建的对象
UserService userService=context.getBean("userService",UserService.class);
userService.add();
}
5.4、注入属性-内部Bean
<bean id="emp" class="com.company.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="Andy"></property>
<property name="gender" value="女"></property>
<!--设置对象类型属性-->
<property name="dept">
<bean id="dept" class="com.company.bean.Dept"><!--内部bean赋值-->
<property name="dname" value="宣传部门"></property>
</bean>
</property>
</bean>
一个部门有多个员工,一个员工对应一个部门。
案例:
package com.company.bean;
//部门类
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return "Dept{" +
"dname='" + dname + '\'' +
'}';
}
}
package com.company.bean;
//员工类
public class Emp {
private String ename;
private String gender;
//员工属于某一个部门,使用对象形式表示
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
public void add(){
System.out.println(ename+"::"+gender+"::"+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 -->
<bean id="emp" class="com.company.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="Andy"></property>
<property name="gender" value="女"></property>
<!--设置对象类型属性-->
<property name="dept">
<bean id="dept" class="com.company.bean.Dept"><!--内部bean赋值-->
<property name="dname" value="宣传部门"></property>
</bean>
</property>
</bean>
</beans>
@Test
public void testBean2(){
//1.加载spring配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo3.xml");
//2.获取配置创建的对象
Emp emp=context.getBean("emp", Emp.class);
emp.add();
}
5.5、注入属性-级联赋值
<!--方式一:级联赋值-->
<bean id="emp" class="com.company.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="Andy"></property>
<property name="gender" value="女"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.company.bean.Dept">
<property name="dname" value="公关部门"></property>
</bean>
<!--方式二:级联赋值-->
<bean id="emp" class="com.company.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="jams"></property>
<property name="gender" value="男"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="技术部门"></property>
</bean>
<bean id="dept" class="com.company.bean.Dept">
</bean>
6、IOC操作Bean管理( xml方式注入集合属性 )
6.1、注入数组类型属性
<bean id="stu" class="com.company.demo1.Stu">
<!-- 数组类型属性注入 -->
<property name="courses">
<array>
<value>java课程</value>
<value>数据库课程</value>
</array>
</property>
6.2、注入List集合类型属性
<!--list类型属性注入-->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
6.3、注入Map集合类型属性
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
6.4、注入set集合类型属性
<!--set类型属性注入-->
<property name="sets">
<set>
<value>MySql</value>
<value>Redis</value>
</set>
</property>
</bean>
案例:
package com.company.demo1;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
//(1)创建类,定义数组、list、map、set 类型属性,生成对应 set 方法
public class Stu {
//1 数组类型属性
private String[] courses;
//2 list集合类型属性
private List<String> list;
//3 map集合类型属性
private Map<String, String> maps;
//4 set集合类型属性
private Set<String> sets;
public void setSets(Set<String> sets) {
this.sets = sets;
}
public void setCourses(String[] courses) {
this.courses = courses;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void test(){
System.out.println(Arrays.toString(courses));
System.out.println(list);
System.out.println(maps);
System.out.println(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 id="stu" class="com.company.demo1.Stu">
<!-- 数组类型属性注入 -->
<property name="courses">
<array>
<value>java课程</value>
<value>数据库课程</value>
</array>
</property>
<!--list类型属性注入-->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
<!--map类型属性注入-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!--set类型属性注入-->
<property name="sets">
<set>
<value>MySql</value>
<value>Redis</value>
</set>
</property>
</bean>
</beans>
package com.company.test;
import com.company.demo1.Stu;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.TestConstructor;
public class Test_demo1 {
@Test
public void test(){
//1.加载配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo1.xml");
//2.获取配置文件对象
Stu stu=context.getBean("stu",Stu.class);
stu.test();
}
}
6.5、注入对象集合类型属性
<bean id="stu" class="com.company.demo2.Stu">
<!-- 注入list集合类型的值,值是对象 -->
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<!-- 创建多个course对象-->
<bean id="course1" class="com.company.demo2.Course">
<property name="cname" value="Spring框架"></property>
</bean>
<bean id="course2" class="com.company.demo2.Course">
<property name="cname" value="MYsql框架"></property>
</bean>
案例:
package com.company.demo2;
public class Course {
//课程名称
private String cname;
public void setCname(String cname) {
this.cname = cname;
}
@Override
public String toString() {
return "Course{" +
"cname='" + cname + '\'' +
'}';
}
}
package com.company.demo2;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
//(1)创建类,定义数组、list、map、set 类型属性,生成对应 set 方法
public class Stu {
//1 数组类型属性
private String[] courses;
//2 list集合类型属性
private List<String> list;
//3 map集合类型属性
private Map<String, String> maps;
//4 set集合类型属性
private Set<String> sets;
//学生所学多门课程
private List<Course> courseList;
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public void setCourses(String[] courses) {
this.courses = courses;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void test(){
System.out.println(Arrays.toString(courses));
System.out.println(list);
System.out.println(maps);
System.out.println(sets);
System.out.println(courseList);
}
}
<?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="stu" class="com.company.demo2.Stu">
<!-- 数组类型属性注入 -->
<property name="courses">
<array>
<value>java课程</value>
<value>数据库课程</value>
</array>
</property>
<!--list类型属性注入-->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
<!--map类型属性注入-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!--set类型属性注入-->
<property name="sets">
<set>
<value>MySql</value>
<value>Redis</value>
</set>
</property>
<!-- 注入list集合类型的值,值是对象 -->
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<!-- 创建多个course对象-->
<bean id="course1" class="com.company.demo2.Course">
<property name="cname" value="Spring框架"></property>
</bean>
<bean id="course2" class="com.company.demo2.Course">
<property name="cname" value="MYsql框架"></property>
</bean>
</beans>
package com.company.test;
import com.company.demo2.Stu;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_demo2 {
@Test
public void test(){
//1.加载配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo2.xml");
//2.获取配置文件对象
Stu stu=context.getBean("stu", Stu.class);
stu.test();
}
}
结果
6.6、把集合注入部分提取出来
-
(1)在spring配置文件中引入名称空间 util
xmlns:util=“http://www.springframework.org/schema/util”
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
<?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"
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"
>
- (2)使用标签提取的list
案例:
package com.company.demo3;
import java.util.List;
public class Book {
//学生所学多门课程
private List<String> list;//创建集合
public void setList(List<String> list) {
this.list = list;
}
public void test(){
System.out.println(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:p="http://www.springframework.org/schema/p"
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"
>
<!--1.提取list集合类型属性的注入-->
<util:list id="booklist">
<value>值一</value>
<value>值二</value>
<value>值三</value>
</util:list>
<!-- 2.使用提取的list-->
<!-- scope="prototype(多实例对象)/singleton(单实例对象)默认"
1,scope="singleton(单实例对象)默认",加载spring配置文件时候创建单实例对象
2,scope="prototype(多实例对象)",不是在加载spring配置文件时候创建对象,而是在调用getBean()方法时候创建多实例对象
-->
<bean id="book" class="com.company.demo3.Book" scope="prototype">
<property name="list" ref="booklist"></property>
</bean>
</beans>
package com.company.test;
import com.company.demo3.Book;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_demo3 {
@Test
public void test(){
//1.加载配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo3.xml");
//2.获取配置文件对象
Book book1=context.getBean("book", Book.class);
book.test();
System.out.println(book1);
}
}
7、 IOC操作Bean管理(FactoryBean )
-
1、Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)
-
2、普通 bean:在配置文件中定义 bean 类型就是返回类型
-
3、工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
- 第一步 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
- 第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
案例:工厂Bean
package com.company.demo4;
public class Course {
private String cname;
public void setCname(String cname) {
this.cname = cname;
}
@Override
public String toString() {
return "Course{" +
"cname='" + cname + '\'' +
'}';
}
}
package com.company.demo4;
import com.company.demo4.Course;
import org.springframework.beans.factory.FactoryBean;
public class MyBean implements FactoryBean<Course> {
/*
* 工厂bean:在配置文件定义的bean类型和返回类型不一样
* 1.创建类,让这个类作为工厂bean,实现接口FactoryBean
* 2.在实现接口的方法里面定义放回的bean类型
* */
@Override
public Course getObject() throws Exception {
//定义返回bean
Course course;
course = new Course();
course.setCname("abc");
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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>
<bean id="myBean" class="com.company.demo4.MyBean">
</bean>
</beans>
package com.company.test;
import com.company.demo4.Course;
import com.company.demo4.MyBean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_demo4 {
@Test
public void test4() {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring5_demo4.xml");
Course course= context.getBean("myBean", Course.class);//返回值类型可以不是定义的bean类型!
System.out.println(course);
}
}
8、 IOC操作Bean管理(Bean 的作用域)
在 Spring 里面,默认情况下,bean 是单实例对象,
下面进行作用域设置:
-
(1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
-
(2)scope 属性值 第一个值 默认值,singleton,表示是单实例对象, 第二个值 prototype,表示是多实例对象
-
(3)singleton 和 prototype 区别
a)singleton 单实例,prototype 多实例 b)设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象 ;设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候创建多实例对象
9、 IOC操作Bean管理(Bean 生命周期)
-
1、生命周期 :从对象创建到对象销毁的过程
-
2、bean 生命周期
(1)通过构造器 创建 bean 实例(无参数构造) (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法) (3)调用 bean 的初始化的方法(需要进行配置初始化的方法) (4)bean 可以使用了(对象获取到了) (5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
-
3、演示 bean 生命周期 :
public class Orders {
private String oname;
//无参数构造
public Orders() {
System.out.println("第一步 执行无参数构造创建 bean 实例");
}
//set方法
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步 调用 set 方法设置属性值");
}
//创建执行的初始化的方法
public void initMethod() {
System.out.println("第三步 执行初始化的方法");
}
//创建执行的销毁的方法
public void destroyMethod() {
System.out.println("第五步 执行销毁的方法");
}
}
<?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参数配置-->
<!--配置初始化方法和销毁方法
初始化方法 init-method="initMethod"
销毁方法 destroy-method="destroyMethod"
-->
<bean id="orders" class="com.company.demo6.Orders" init-method="initMethod" destroy-method="destroyMethod">
<!--这里就是通过set方式(注入属性)赋值-->
<property name="oname" value="手机"></property>
</bean>
</beans>
public class Test_demo6 {
@Test
public void test(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring5_demo6.xml");
Orders orders = context.getBean("orders", Orders.class);
System.out.println("第四步 获取创建 bean 实例对象");
System.out.println(orders);
//手动让 bean 实例销毁
context.close();
}
}
-
4、bean 的后置处理器,bean 生命周期有七步 (正常生命周期为五步,而配置后置处理器后为七步)
(1)通过构造器创建 bean 实例(无参数构造) (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法) (3)*把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization* (4)调用 bean 的初始化的方法(需要进行配置初始化的方法) (5)*把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization* (6)bean 可以使用了(对象获取到了) (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
在前面基础上添加
public class MyBeanPost implements BeanPostProcessor {//创建后置处理器实现类
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之前执行的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之后执行的方法");
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参数配置-->
<!--配置初始化方法和销毁方法
初始化方法 init-method="initMethod"
销毁方法 destroy-method="destroyMethod"
-->
<bean id="orders" class="com.company.demo6.Orders" init-method="initMethod" destroy-method="destroyMethod">
<!--这里就是通过set方式(注入属性)赋值-->
<property name="oname" value="手机"></property>
</bean>
<!--配置后置处理器-->
<bean id="myBeanPost" class="com.company.demo6.MyBeanPost"></bean>
</beans>
10、IOC操作Bean管理(XML自动装配 )
10.1、什么是自动装配
**根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。**
10.2、自动装配过程
-
(1)根据属性名称自动注入
-
(2)根据属性类型自动注入
package com.company.demo5;
public class Emp {
public Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"dept=" + dept +
'}';
}
public void test(){
System.out.println(dept);
}
}
package com.company.demo5;
public class Dept {
@Override
public String toString() {
return "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"
xmlns:p="http://www.springframework.org/schema/p"
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"
>
<!--实现自动装配
Bean标签里面autowire="byName"属性:
autowire="byName",根据名称注入,注入bean的id值和类里面属性名称一样
autowire="byType",根据类型注入,只能定义一个对象类型
-->
<bean id="emp" class="com.company.demo5.Emp" autowire="byName">
<!-- <property name="dept" ref="dept"></property>-->
</bean>
<bean id="dept" class="com.company.demo5.Dept"></bean>
</beans>
import com.company.demo5.Emp;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test_demo5 {
@Test
public void test(){
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo5.xml");
Emp emp=context.getBean("emp",Emp.class);
System.out.println(emp);
}
}
11、IOC操作Bean管理(外部属性文件 )
百度网盘-需要连接池jar包
链接:https://pan.baidu.com/s/1iWPMoRXHUfkoBfhgYu8g7Q
提取码:x9qm
11.1、方式一:直接配置数据库信息
(1)配置Druid(德鲁伊)连接池
(2)引入Druid(德鲁伊)连接池依赖 jar 包
<!--直接配置连接池-->
<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>
11.2、方式二:引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties 格式文件,写数据库信息(jdbc.properties)
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/jdbc
prop.userName=root
prop.password=root
(2)把外部 properties 属性文件引入到 spring 配置文件中 —— 引入 context 名称空间
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
<!-- 引入外部属性文件properites-->
<context:property-placeholder location="classpath:jdbc.properitesd"></context:property-placeholder>
<!-- 配置连接池-->
<bean id="dataSource" class="com.alibab.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>
12、IOC操作Bean管理(基于注解方式 )
12. 1、什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化 xml 配置
12. 2、Spring 针对 Bean 管理中创建对象提供注解
下面四个注解功能是一样的,都可以用来创建 bean 实例
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
12. 3、基于注解方式实现 -对象创建
-
第一步 引入依赖 (引入spring-aop jar包)
链接:https://pan.baidu.com/s/1-S1KDjm4DkCtnygSFqzchA 提取码:414n
-
第二步 开启组件扫描
引入 context 名称空间 <!--二. 开启组件扫描 1.如果扫描多个包,多个包用逗号隔开 2.扫描包上层目录 --> <context:component-scan base-package="com.company.demo1"> </context:component-scan>
-
第三步 创建类,在类上面添加创建对象注解
//添加注解 ,value属性的值可以不写 //默认值是类名称,首字母小写 @Component(value = "userService")// <bean id="userService" class=""/> public class UserService { public void add(){ System.out.println("service add::::"); } }
12. 4、开启组件扫描细节配置
<!--示例1
use-default-filters="false”表示现在不使用默认filter,自己配置filtercontext:
context:include-filter ,设置扫描哪些内容
扫描base-package="com.company.demo1"这个包下面所有注解为@Controller的类(expression=" .Controller")
-->
<context:component-scan base-package="com.company.demo1" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--示例2
下面配置扫描包所有内容
context:exclude-filter:设置哪些内容不进行扫描
除了注解为@Controller的类(expression=" .Controller")不扫描,其他的类全部扫描
-->
<context:component-scan base-package="com.company.demo1" >
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
12. 5、基于注解方式实现 -属性注入
-
(1)@Autowired:根据属性类型进行自动装配
-
(2)@Qualifier:根据属性名称进行注入,这个@Qualifier 注解的使用,和上面@Autowired 一起使用
//2.和Autowired一起使用,根据名称注入属性 @Autowired @Qualifier(value = "userDaoImpl1")
-
(3)@Resource:可以根据类型注入,也可以根据名称注入(它属于javax包下的注解,不推荐使用!)
//3.根据类型注入属性 @Resource //根据名称注入 @Resource(name = "userDaoImpl1") private UserDao userdao;
-
(4)@Value:注入普通类型属性
//4.普通类型注入属性 @Value(value = "abc") private String name;
12. 6、基于注解方式实现 -对象创建和属性注入(案例1,xml配置)
- 接口
public interface UserDao {
public void add();
}
- 实现接口类1
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao{
@Override
public void add(){
System.out.println("UserDao add;;;;;");
}
}
- 实体类2
import com.company.demo1.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
//添加注解 ,value属性的值可以不写
//默认值是类名称,首字母小写
//注解可以是@Repository/@Component/@Service/@Controller
@Service
@Component(value = "userService")// <bean id="userService" class=""/>
public class UserService {
//不需要添加set()方法
//添加注入属性注解
//1.根据类型注入属性 @Autowired
//2.和Autowired一起使用,根据名称注入属性
/* @Autowired
@Qualifier(value = "userDaoImpl1")
*/
//3.根据类型注入属性 @Resource
//根据名称注入
@Resource(name = "userDaoImpl1")
private UserDao userdao;
//4.普通类型注入属性
@Value(value = "abc")
private String name;
public void add(){
System.out.println(name);
System.out.println("service add::::");
userdao.add();
}
}
- 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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>
<!--一.引用依赖jar包 spring-aop -->
<!--二. 开启组件扫描
1.如果扫描多个包,多个包用逗号隔开
2.扫描包上层目录
-->
<context:component-scan base-package="com.company.demo1">
</context:component-scan>
<!--三.创建类添加注解
(1) @Component
(2) @Service
(3) @Controller
(4)@Repository
-->
<!--示例1
use-default-filters="false”表示现在不使用默认filter,自己配置filtercontext:
context:include-filter ,设置扫描哪些内容
扫描base-package="com.company.demo1"这个包下面所有注解为@Controller的类(expression=" .Controller")
-->
<context:component-scan base-package="com.company.demo1" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--示例2
下面配置扫描包所有内容
context:exclude-filter:设置哪些内容不进行扫描
除了注解为@Controller的类(expression=" .Controller")不扫描,其他的类全部扫描
-->
<context:component-scan base-package="com.company.demo1" >
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
- 测试类
import com.company.demo1.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Vector;
public class TestDemo1 {
@Test
public void test(){
ApplicationContext context=
new ClassPathXmlApplicationContext("spring5_demo1.xml");
UserService userService=context.getBean("userService",UserService.class);
System.out.println(userService);
userService.add();
}
}
12. 7、完全注解开发(案例2,配置类)
** //这里就不需要XML配置文件,用@Configuration 作为配置类,代替XML配置文件**
- 配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration//作为配置类,代替XML配置文件
@ComponentScan(basePackages ={"com.company"})//组件扫描
public class Spring5Config_demo2 {
}
- 测试类
import com.company.demo1.config.Spring5Config_demo2;
import com.company.demo1.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemo2 {
@Test
public void test(){
//这里就不需要XML配置文件,用@Configuration 作为配置类,代替XML配置文件
ApplicationContext context =
new AnnotationConfigApplicationContext(Spring5Config_demo2.class);
UserService userService=context.getBean("userService",UserService.class);
System.out.println(userService);
userService.add();
}
}