Spring5框架-IOC容器
Spring5框架
Spring包下载快照
一.Spring简绍
1什么是Spring
1.Spring是轻量级的开源的JAVAEE框架,可以解决企业应用开发的复杂性
2.Spring有两个核心的部分:IOC和AOP
- IOC:控制反转,把创建对象过程交给Spring进行管理
- Aop:面向切面,不修改源代码进行功能的增强
2 主要
一句话概况:Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器(框架)
3 Spring的特点
- 方便解耦,简化开发
- Aop编程支持
- 方便程序测试
- 方便和其他框架进行整合
- 方便进行事物操作
- 降低API开发难度
4组成
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .
5 组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。
每个模块的功能如下:
- 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory ,它是工厂模式的实现。 BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
- Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象Spring AOP 模块为基于Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。
- Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次
结构。 - Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
- Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
- Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText和 POI。
6 拓展
- Spring Boot与Spring Clou Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务;
- Spring Cloud是基于Spring Boot实现的;
- Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
- Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 ,
- Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
- SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot。
二.IOC基础
1什么是IOC
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中也就是把对象创建和对象之间的调用过程,交给spring进行管理使用IOC目的:为了耦合度降低
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,
新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用
时再从Ioc容器中取出需要的对象。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为
一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现
控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
2.IOC的底层原理
1.xml解析、工厂模式、反射
步骤:
- xml配置文件,配置创建的对象
<bean id=“dao” class=“com.spring.UserDo”></bean> - 用service类和dao类 创建工厂
class UserFactory {public static UserDao getDao() {String classValue = class属性值;//xml解析Class class = Class.forName(classValue);//通过反射创建对象return (UserDao)class.newInstance();}}
3.IOC接口
1.IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
2.Spring提供IOC容器是实现两种方式
- BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用 特点:加载配置文件的时候不会创建对象,在获取对象才去创建对象
- ApplicationContext:beanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用 特点:加载配置文件的时候就会把在配置文件对象进行创建
3.导包
如果有的包没有可以通过我这里下载全部java的jar包
导入相关的Spring5相关的jar包
- Beans
- Core
- Context
- Expression
- logging–在Spring5的jar包中没有
在IDEA中先导入jar包
点击ok 到Apply
出现下图的三角号就行
3.创建IOC代码
1.创建bean配置文件,在配置文件配置中创建对象
1.bean管理
- Spring创建对象
- Spring注入属性
2.bean管理操作
- 基于xml配置文件方式实现
- 基于注解方式实现
一般我们创建普通类是以下创建的
public class User {public void add() {System.out.println("add....");}
}
1. 用IOC基于xml创建
(1)Spring配置文件使用xml格式
在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
配置Bean1.xml中的属性讲解
- id属性:唯一标识
- class属性:类全路径(包类路径)
<?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对象创建--><bean id="User" class="com.Spring.IOC.User"></bean>
</beans>
在开始前我们最好将@Test包引入以便我们好进行测试
加载配置bean文件
public class TestSpring5 {@Testpublic void testAdd(){// 加载Spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");//获取配置创建对象User user = context.getBean("User",User.class);System.out.println(user);user.add();}
2.基于xml方式注入属性
1.DI:依赖注入,就是属性注入属性
- 第一张建立set方法注入
public class Book {private String bname;
private String bauthor;
public void setBname(String bnaem) {this.bname = bname;}public void setBauthor(String bauthor){this.bauthor = bauthor;}
}
xml配置
<!--set方法注入属性--><bean id="book" class="com.Spring.IOC.Book"><!--使用property完成属性注入name:类里面属性名称value:向属性注入的值--><property name="bname" value="java开发"></property><property name="bauthor" value="黑马"></property></bean>
- 有参数构造注入
public class Orders {private String oname;private String oaddress;public Orders(String oname, String oaddress) {this.oname = oname;this.oaddress = oaddress;}}
xml配置
<!--有参数构造注入属性--><bean id="order" class="com.Spring.IOC.Orders"><constructor-arg name="oname" value="腊肠"></constructor-arg><constructor-arg name="oaddress" value="中国"></constructor-arg></bean>
2.p 名称空间注入
可以简化基于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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="book" class="com.Spring.IOC.Book" p:bname="Spring开发" p:bauthor="黑马"></bean>
</beans>
java代码
public class Book {private String bname;private String bauthor;@Overridepublic String toString() {return "Book{" +"bname='" + bname + '\'' +", bauthor='" + bauthor + '\'' +'}';}public void setBauthor(String bauthor) {this.bauthor = bauthor;}public void setBname(String bname) {this.bname = bname;}
}
测试代码
@Testpublic void testBook(){ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");Book book = context.getBean("book",Book.class);System.out.println(book);book.toString();}
3.xml注入特殊值
- 注入空值
将value单独设置为null
<bean id="book" class="com.Spring.IOC.Book"><!--使用property完成属性注入name:类里面属性名称value:向属性注入的值--><property name="bname" value="java开发"></property><property name="bauthor"><null></null></property></bean>
- 特殊符号的设置
可以使用转义字符或者用<![CDATA[<黑马程序员>]]>这样写
<bean id="book" class="com.Spring.IOC.Book"><!--使用property完成属性注入name:类里面属性名称value:向属性注入的值--><property name="bname" value="<java开发>"></property><property name="bauthor"><value><![CDATA[<黑马程序员> ]]></value></property></bean>
4.注入属性-外部bean
- 创建两个类service类和Userdao类 UserDaoImpl类
public interface UserDao {public void upadte();
}
public class UserDaoImpl implements UserDao {@Overridepublic void upadte() {System.out.println("dao update....");}
}
- 在service调用dao里面的方法
public class UserService {//创建UserDao类型属性,生产set方法private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void add() {System.out.println("add Service....");userDao.upadte();}
}
- 配置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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.Spring.IOC.UserService"><!--注入UserDao对象name属性值:类里面属性名称ref属性:创建userDao对象bean标签id值--><property name="userDao" ref="userDaoImpl"></property>
</bean><bean id="userDaoImpl" class="com.Spring.dao.UserDaoImpl"></bean></beans>
- 测试
public void testUserDao(){ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");UserService userService = context.getBean("userService",UserService.class);userService.add();}
5.注入属性-内部bean
- 1.一对多关系:部门和员工
一个部门有多个员工,一个员工属于一个部门 - 2.实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行标识
public class Emp {private String ename;private String gender;private Dept dept;
//员工属于某一个部门,使用对象表示public void setEname(String ename) {this.ename = ename;}public void setGender(String gender) {this.gender = gender;}public void setDept(Dept dept) {this.dept = dept;}public String toString() {return "Emp{" +"ename='" + ename + '\'' +", gender='" + gender + '\'' +", dept=" + dept +'}';}public void add(){System.out.println(ename+"11"+gender+".."+dept);}
}
public class Dept {private String dname;public void setDname(String dname) {this.dname = dname;}@Overridepublic String toString() {return "Dept{" +"dname='" + dname + '\'' +'}';}
}
xml配置
<!--内部bean--><bean id="emp" class="com.Spring.dao.Emp"><!--设置两个普通属性--><property name="ename" value="张三"></property><property name="gender" value="男"></property><!--设置对象类型属性--><property name="dept"><bean id="dept" class="com.Spring.dao.Dept"><property name="dname" value="技术部门"></property></bean></property></bean>
测试
@Testpublic void tetsemp() {ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");Emp emp = context.getBean("emp",Emp.class);emp.add();}
6.注入属性-级联赋值
第一张写法
<!--级联赋值--><bean id="emp" class="com.Spring.dao.Emp"><!--设置两个普通属性--><property name="ename" value="张三"></property><property name="gender" value="男"></property><!--级联赋值--><property name="dept" ref="dept"></property></bean><bean id="dept" class="com.Spring.dao.Dept"><property name="dname" value="技术部"></property></bean>
第二种写法下面这种写法要将dept的get方法创建出来
<!--级联赋值--><bean id="emp" class="com.Spring.dao.Emp"><!--设置两个普通属性--><property name="ename" value="张三"></property><property name="gender" value="男"></property><!--级联赋值--><property name="dept" ref="dept"></property><property name="dept.dname" value="技术"></property></bean><bean id="dept" class="com.Spring.dao.Dept"><!-- <property name="dname" value="技术部"></property>--></bean>
3.IOC操作Bean管理,xml注入集合
java类创建
public class Stu {//数组private String[] courses;//list集合private List<String> list;//map集合private Map<String,String> maps;//set集合private Set<String> 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 setSets(Set<String> sets) {this.sets = sets;}public void print(){System.out.println(Arrays.toString(courses));System.out.println(list);System.out.println(maps);System.out.println(sets);}
}
测试类
public void tetstu() {ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");Stu stu = context.getBean("stu", Stu.class);stu.print();}
xml配置各种集合的用法数组、list、Map、set
<?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.Spring.Collection.Stu"><!--数组类型注入--><property name="courses"><array><value>java课程</value><value>javaweb课程</value></array></property><!--list类型注入--><property name="list"><list><value>张三</value><value>李四</value></list></property><property name="maps"><map><entry key="java" value="java"></entry><entry key="php" value="php"></entry></map></property><property name="sets"><set><value>入门到放弃</value><value>一步一个台阶</value></set></property></bean>
</beans>
当集合为一个对象时进行xml配置,在上面的基础上加个课程类
package com.Spring.Collection;
//课程类
public class Course {private String cname;//课程名称public void setCname(String cname) {this.cname = cname;}@Overridepublic String toString() {return "Course{" +"cname='" + cname + '\'' +'}';}
}
public class Stu {//数组private String[] courses;//list集合private List<String> list;//map集合private Map<String,String> maps;//set集合private Set<String> sets;
//学生学习多个课程private List<Course> coursesList;public void setCoursesList(List<Course> coursesList) {this.coursesList = coursesList;}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 setSets(Set<String> sets) {this.sets = sets;}public void print(){System.out.println(Arrays.toString(courses));System.out.println(list);System.out.println(maps);System.out.println(sets);System.out.println(coursesList);}
}
测试类
@Testpublic void tetstu() {ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");Stu stu = context.getBean("stu", Stu.class);stu.print();}
xml里面添加集合对象
<!--集合类型的属性注入--><bean id="stu" class="com.Spring.Collection.Stu"><!--数组类型注入--><property name="courses"><array><value>java课程</value><value>javaweb课程</value></array></property><!--list类型注入--><property name="list"><list><value>张三</value><value>李四</value></list></property><property name="maps"><map><entry key="java" value="java"></entry><entry key="php" value="php"></entry></map></property><property name="sets"><set><value>入门到放弃</value><value>一步一个台阶</value></set></property><!--注入List集合对象--><property name="coursesList"><list><ref bean="course1"></ref><ref bean="course2"></ref></list></property></bean><!--创建多个course对象--><bean id="course1" class="com.Spring.Collection.Course"><property name="cname" value="Spring 框架"></property></bean><bean id="course2" class="com.Spring.Collection.Course"><property name="cname" value="MyBatis框架"></property></bean>
将集合注入部分提取出来
先创建集合类
public class Book {private List<String> bname;@Overridepublic String toString() {return "Book{" +"bname='" + bname + '\'' +'}';}public void setBname(List<String> bname) {this.bname = bname;}
}
xml进行集合提取配置使用util标签
<?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.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--提取List集合类型属性注入-->
<util:list id="booklist"><value>java开发</value><value>php开发</value>
</util:list><!--提取List集合类型属性注入使用--><bean id="book" class="com.Spring.IOC.Book"><property name="bname" ref="booklist"></property></bean>
</beans>
测试
@Testpublic void testBook(){ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");Book book = context.getBean("book",Book.class);System.out.println(book);book.toString();}
Properties注入
<property name="info">
<props>
<prop key="学号">20190604</prop>
<prop key="性别">男</prop>
<prop key="姓名">小明</prop>
</props>
</property>
4.bean管理
1.普通bean
在配置文件中定义bean类型就是返回类型
2.工程bean就是FactoryBean
在配置文件定义bean类型可以和返回类型不一样
- 创建类,让这个类作为工厂bean,实现接口FactoryBean
- 实现接口里面的方法,在实现的方法中定义返回的bean类型
创建一个不同的返回值
public class MyBean implements FactoryBean<Course> {//定义返回Bean@Overridepublic Course getObject() throws Exception {Course course = new Course();course.setCname("张思思");return course;}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic 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 id="myBean" class="com.Spring.Collection.MyBean"></bean>
</beans>
public class Course {private String cname;//课程名称public void setCname(String cname) {this.cname = cname;}@Overridepublic String toString() {return "Course{" +"cname='" + cname + '\'' +'}';}
}
最终是实现Course的类的对象
@Testpublic void myBean() {ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");Course mybean = context.getBean("myBean", Course.class);System.out.println(mybean);}
5.Bean的作用域
Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,
bean就是由IoC容器初始化、装配及管理的对象
几种作用域中,request、session作用域仅在基于web的应用中使用(不必关心你所采用的是什么web
应用框架),只能用在基于web的Spring ApplicationContext环境。
Singleton
当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对
bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是
在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象
都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。要在XML中将bean定义成
singleton,可以这样配置:
1 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">
测试
@Test
public void test03(){ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);
}
Prototype
当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会
导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)
时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是
当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经
验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。在
XML中将bean定义成prototype,可以这样配置:
<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>
或者
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
Request
当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP
请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring
ApplicationContext情形下有效。考虑下面bean定义:
<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实
例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例
的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的
状态变化。当处理请求结束,request作用域的bean实例将被销毁。
Session
当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域
仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的
userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作
用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据
userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session
最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。
1.设置创建Bean实例是单实例还是多实例
在Spring下默认是单实例对象
1.在Spring配置文件bean标签里面有属性用于设置单实例还是多实例
scope="" 就是设置多实例还是单实例
- prototype是多实例
- singleton是单实例也是默认实例
<?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="book" class="com.Spring.IOC.Book" scope="prototype"><property name="bname" value="java开发"></property>
</bean>
</beans>
public class Book {private String bname;public void setBname(String bname) {this.bname = bname;}
}
prototype与singleton的区别
- 设置scope是singleton的时候,加载Spring配置文件就会创建单实例对象
- scope是prototype的时候,不是在加载Spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象
6.Bean的生命周期
1.过程
- 通过构造器创建Bean实例(无参构造)
- 为Bean的属性设置值和对其他Bean引用(调用set方法)
- 调用Bean的初始化方法(需要进行配置初始化方法)
- Bean可以使用了(对象获取到了)
- 当容器关闭时,调用Bean的销毁的方法(需要进行配置销毁方法)
public class Orders {private String oname;public Orders() {System.out.println("1.执行无参数构造创建Bean实例");}public void setOname(String oname) {this.oname = oname;System.out.println("2.调用set方法设置属性值");}public void initMethod(){System.out.println("3.执行初始化的方法");}public void destroyMethod(){System.out.println("5.执行销毁方法");}
}
测试类
@Testpublic void testBean() {ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");Orders orders = context.getBean("orders2",Orders.class);System.out.println("4.获取创建Bean实例对象");System.out.println(orders);//手动销毁Bean实例((ClassPathXmlApplicationContext) context).close();}
xml配置里面要加上init-method 和destory-method这两个方法都在Orders类里面创建
<bean id="orders2" class="com.Spring.Collection.Orders" init-method="initMethod" destroy-method="destroyMethod"><property name="oname" value="手机"></property></bean>
2.添加后置处理器后有七步
- 通过构造器创建Bean实例(无参构造)
- 为Bean的属性设置值和对其他Bean引用(调用set方法)
- 把Bean实例传给Bean后置处理器的方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}
- 调用Bean的初始化方法(需要进行配置初始化方法)
- 把Bean实例传递给Bean后置处理器的方法
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
- Bean可以使用了(对象获取到了)
- 当容器关闭时,调用Bean的销毁的方法(需要进行配置销毁方法)
添加后置处理器方法实现BeanPostProcessor,创建后置处理器
public class MyBeanPost implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("在初始化之前执行的方法");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("在初始化方法之后执行的方法");return bean;}
}
public class Orders {private String oname;public Orders() {System.out.println("1.执行无参数构造创建Bean实例");}public void setOname(String oname) {this.oname = oname;System.out.println("2.调用set方法设置属性值");}public void initMethod(){System.out.println("3.执行初始化的方法");}public void destroyMethod(){System.out.println("5.执行销毁方法");}
}
只需要将配置的后置对象加入到配置的文件中,在里面的其他配置实例都会有后置对象
<?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="orders2" class="com.Spring.Collection.Orders" init-method="initMethod" destroy-method="destroyMethod"><property name="oname" value="手机"></property></bean><!--配置后置处理器--><bean id="myBeanPost" class="com.Spring.Collection.MyBeanPost"></bean>
</beans>
7.IOC操作Bean管理(xml自动装配)
在上面的我们xml的装配都说手动装配
1.什么是自动装配
- 根据指定装配规则(属性名称或者属性类型)Spring自动将匹配的属性值进行注入
bean标签属性autowire,配置自动装配
autowire属性常用两个值:
byName根据属性名称注入 注入值bean的id值和类属性名称一样
byType更具属性类型注入–属性类型
下面是ByName和byType
<?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标签属性autowire,配置自动装配
autowire属性常用两个值:byName根据属性名称注入 注入值bean的id值和类属性名称一样byType更具属性类型注入
--><bean id="emp2" class="com.Spring.autowire.Emp" autowire="byName"><!--<bean id="emp2" class="com.Spring.autowire.Emp" autowire="byType">--><!--<property name="dept" ref="dept"></property>-->
</bean><bean id="dept" class="com.Spring.autowire.Dept"></bean>
</beans>
@Autowired与@Resource异同:
- @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
- @Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果
要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我
们想使用名称装配可以结合@Qualifier注解进行使用 - @Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果
没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在
setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是
需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先
byName。
8.IOC操作Bean管理(外部属性文件)
1.配置数据库信息
- 1.配置德鲁伊连接池
内部创建信息
<?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="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql://loaclhost/user" ></property><property name="username" value="root" ></property><property name="password" value="" ></property></bean>
</beans>
外部创建文件jabc.properties文件进行数据库的连接
再把外部properties文件属性引入到Spring配置文件中
引入context
<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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://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>
9.IOC操作Bean管理(基于注解)
1.什么是注解
注解是代码特殊标记、格式:@注解名称(属性名称=属性值)
使用注解,注解在作用在类上面、方法上面、属性上面,位置不一样,作用范围不一样
使用注解的目的:简化xml配置
2.Spring针对Bean管理中创建对象提供注解
- @Component
- @Service
- @Controller
- @Repository
上面的四个注解功能一样,都可以用来创建Bean实例
我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!
- @Component三个衍生注解
为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。 - @Controller:web层
- @Service:service层
- @Repository:dao层
写上这些注解,就相当于将这个类交给Spring管理装配了!
1.基于注解方式实现对象创建
1.引入依赖引入Spring的AOPjar包
2.开启xml的组件扫描xml里面需要配置context
<?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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--开启组件扫描如果扫描多个包用逗号隔开扫描包上层目录--><context:component-scan base-package="com.Spring.service,com.Spring.dao"></context:component-scan>
</beans>
实现类,可以将@的四个都可以实现
import org.springframework.stereotype.Component;
//value可以不写,不写的话就默认类名的首字母小写
@Component(value="userService") //<bean id="userService" class="">
public class UserService {public void add(){System.out.println("service add...");}
}
测试代码
@Testpublic void testService(){ApplicationContext context = new ClassPathXmlApplicationContext("bean5.xml");UserService service = context.getBean("userService",UserService.class);System.out.println(service);service.add();}
限制扫描的范围
<?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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--开启组件扫描如果扫描多个包用逗号隔开扫描包上层目录--><context:component-scan base-package="com.Spring.service,com.Spring.dao"></context:component-scan><!-- 实例一限制扫描的范围use-default-filters="false"表示现在不使用默认filter,自己配置filtercontext:include-filter设置扫描那些内容expression="org.springframework.stereotype.Controller"只扫描Controller这个方式--><context:component-scan base-package="com.Spring" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan><!--示例二下面配置扫描包所有内容context:exclude-filter:设置那些内容不扫描--><context:component-scan base-package="com.Spring"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>
</beans>
2.基于注解方式实现属性注入
- @AutoWired :根据属性类型进行自动装配
实现:把Service和dao对象创建,在Service和dao类田间创建对象
public class UserService {@Autowiredprivate UserDao userDao;public void add() {System.out.println("add Service....");userDao.add();}
}
@Repository
public class UserDaoImpl implements UserDao {public void add() {System.out.println("dao add....");}
}
public interface UserDao {public void add();
}
<?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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--开启组件扫描如果扫描多个包用逗号隔开扫描包上层目录--><context:component-scan base-package="com.Spring.service,com.Spring.dao"></context:component-scan></beans>
@Testpublic void testService(){ApplicationContext context = new ClassPathXmlApplicationContext("bean5.xml");UserService service = context.getBean("userService",UserService.class);service.add();}
- @Qualifier :根据属性名称进行注入
@Service
public class UserService {@Autowired//根据类型注入@Qualifier(value = "userDaoImpl")//根据名称注入private UserDao userDao;public void add() {System.out.println("add Service....");userDao.add();}
}
- @Resource :可以根据类型注入,也可以根据名称注入
@Service
public class UserService {//@Resource//根据类型注入@Resource(name = "userDaoImpl1") //根据名称注入private UserDao userDao;public void add() {System.out.println("add Service....");userDao.add();}
}
- @Value:注入普通类型属性
@Service
public class UserService {private UserDao userDao;@Value(value = "张三")private String name;public void add() {System.out.println("add Service"+name);}
}
. 可以不用提供set方法,直接在直接名上添加@value(“值”)
@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {@Value("秦疆")
// 相当于配置文件中 <property name="name" value="秦疆"/>
public String name;
}
.如果提供了set方法,在set方法上添加@value(“值”);
@Component("user")
public class User {public String name;
@Value("秦疆")
public void setName(String name) {this.name = name;
}
}
3.完全注解开发
1.创建配置类,替代xml配置文件
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration //作为配置类,替代xml配置文件
@ComponentScan(basePackages = ("com.Spring")) //加上路径
public class SpringConfig {}
实现配置类
@Testpublic void test(){//加载配置类ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);}
三还有什么问题可以留言给我,会尽心解答的,觉得文章不错的话点个赞把
Spring5框架-IOC容器相关推荐
- Spring5 - 向IOC容器中添加组件的4种方式
文章目录 概述 方式一: @CompentScan 适用场景 Code 方式二: @Bean 适用场景 Code 方式三: @Import 适用场景 Code Demo1 Code Demo2 + 实 ...
- Spring框架—IoC容器
首先我们需要了解一下是什么是IoC.IoC是Spring的核心技术之一,全称是Inversion of Control(控制反转).最原始的创建对象的方法就是通过new来实现(手动的编写代码实现),而 ...
- Spring5的IOC容器
Spring5 中的IOC容器 1.IOC的概念:(控制反转) 2.IOC底层原理: 3.IOC的两个接口: 4.Bean管理(基于xml方式): 5.bean的作用域和生命周期 6.自动装配 7.外 ...
- Spring框架IOC容器,依赖注入,控制反转
Spring的配制文件中 以上标签的属性id是不是必须的?不是必须的,如果定义id,那么其它的bean就可以通过此name来引用id 创建beans.xml <?xml version=&quo ...
- Spring框架—IOC容器—属性赋值的几种方式
目录 一.常用的赋值方式 1.1 set注入 1.1.1 ApplicationContext.xml配置文件 1.1.2 测试类: 1.1.2 控制台输出: 1.2 构造注入 1.2.1 修改Stu ...
- Spring5框架(上) IOC
Spring5框架 IOC 前言 Spring框架概述 IOC容器 底层原理 Bean管理XML方式(创建对象和set注入属性) 注入集合类型属性1 IOC操作Bean管理 Bean管理(工厂Bean ...
- 001 spring5框架:java类工程,IOC:实体类表示表关系,AOP,JdbcTemplate模板,事务操作,Spring5 框架新功能:日志,为空注解,函数式风格,juint,Webflux
1. Spring5 框架(Spring5 Framework)介绍 1.1 概念 1.Spring 是轻量级的开源的 JavaEE 框架 2.Spring 可以解决企业应用开发的复杂性 3.Spri ...
- 请解释下Spring 框架中的IOC 容器?
Spring 中的org.springframework.beans 包和org.springframework.context 包构成了Spring 框架IOC 容器的基础. BeanFactory ...
- Spring5 框架
Spring5 框架 一.Spring概述 Spring是轻量级的开源的JavaEE框架. Spring可以解决企业应用开发的复杂性. Spring有两个核心部分:IOC和AOP. IOC:控制反转, ...
最新文章
- 公司Joomla项目笔记1
- Linux驱动之LCD驱动编写
- hibernate框架int和Integer类型区别
- Leetcode 103. 二叉树的锯齿形层次遍历 解题思路及C++实现
- 免费获取 Kaspersky Small Office Security 90 天授权
- tftp服务器_Transfer for Mac(TFTP服务器)
- samba 端口_无需公网IP,易有云支持SAMBA远程连接家里设备
- Matlab图像处理相关
- 商业认知,新的一年已经开始,许多老板都制订了新的目标
- html 增加和删除一行,关于JS点击增加一行,点击删除一行的问题?
- 调查了 2 万多名 Python 开发者,有了这些发现!
- 中国人工智能学会通讯——基于视频的行为识别技术 1.5 基于深度学习的视频识别方法...
- 已安装jre1.7的情况下安装jdk1.6
- vue项目开发中使用插件流程
- js 怎样把定时器弄成同步的
- 个人学习进度(第四周)
- JS 表单submit() 提交无效的问题
- 分享21个超棒的单页面HTML作品集展示模板
- windows10安装更新很慢ndows,win10系统更新后运行速度变慢的解决方法 - 系统家园...
- WPF半圆形导航菜单
热门文章
- docker容器安装配置及创建容器
- 消息队列-beanstalkd
- 光通量发光强度照度亮度关系_单位面积光功率和照度,光强,亮度,光通量怎么换算?...
- 关于单词:On-premises的含义
- iOS进阶 - pod install 与 pod update 读这一篇就够了
- IOS cocoapods镜像源更新
- Python实现替换照片人物背景,精细到头发丝(附上代码) | 机器学习
- Unity Run Time Gizmos
- 相干布居囚禁(CPT)原子钟的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- PET图像的SUV计算