Spring--IOC
IOC
一、概念
二、原理
-
xml解析
-
工厂模式
-
反射
class UserFactory{ public static UserDao getDao(){ String classValue = class属性值;//xml解析 Class class = Class.forName(classValue);//通过反射创建对象 return (UserDao)class.newInstance(); } }
三、IOC(接口)
- IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
- Spring提供IOC容器实现两种方式:(2个接口)
- 功能:加载配置文件,创建对象
- beanfactory:
- IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用
- ApplicationContext
- beanfactory接口的子接口,提供更加强大的功能,一般面向开发人员使用
- 2个接口的区别:
- beanfactory:加载配置文件时不会创建对象,在获取/使用对象才创建对象
- ApplicationContext:加载配置文件时就创建对象
- ApplicationContext接口实现类
四、IOC操作Bean管理
4.1 什么是Bean管理
4.2 IOC操作Bean管理(基于xml方式)
4.2.1 基于xml方式创建对象
4.2.2 基于xml方式中注入属性
第一种方式:set注入
DI:依赖注入,就是注入属性
//类的编写
package cn.future.Spring5;
public class Book {
//创建属性
private String bName;
private String bAuthor;
//创建属性对应的set方法
public void setbName(String bName) {
this.bName = bName;
}
public void setbAuthor(String bAuthor) {
this.bAuthor = bAuthor;
}
public static void main(String[] args) {
Book book = new Book();
book.setbName("hello");
}
}
<!-- xml编写 -->
<!-- set方法注入属性-->
<bean id="book" class="cn.future.Spring5.Book" >
<!-- 使用property完成属性注入
name:类的属性名称
value:向属性注入的值
-->
<property name="bName" value="易筋经"></property>
<property name="bAuthor" value="达摩"></property>
</bean>
//测试类
public class BookSpring5 {
@Test
public void testBook1(){
//1.加载spring配置文件
ApplicationContext context = new ClasspathXmlApplicationContext("bean1.xml");
//2.获取配置创建的对象
Book book = context.getBean("book",Book.class);
System.out.println(book);
book.testDemo();
}
}
第二种方法:有参构造注入
-
package cn.future.Spring5; public class Order { private String oname; private String address; //有参数构造 public Order(String oname, String address) { this.oname = oname; this.address = address; } public void show(){ System.out.println(oname+address); } }
<bean id="order" class="cn.future.Spring5.Order"> <constructor-arg name="address" value="电脑"></constructor-arg> <constructor-arg name="oname" value="戴尔"></constructor-arg> </bean>
public class testSpring5 { @Test public void testAdd(){ //1.加载spring配置文件 ApplicationContext context = new ClasspathXmlApplicationContext("bean1.xml"); //2.获取配置创建的对象 User user = context.getBean("user", User.class); System.out.println(user); user.add(); } }
4.2.3 xml注入其他类型属性
字面量
- null值
- 属性值包含特殊符号
4.2.4 注入属性-外部bean
4.2.5 注入属性-内部bean和级别赋值
4.2.6 注入集合类型属性
不提取方法
<?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="cn.future.Spring5.Stu">
<!-- 数组类型 -->
<property name="strs">
<array>
<value>java</value>
<value>python</value>
<value>MysqL</value>
</array>
</property>
<!-- list类型注入 -->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
<!-- map集合 -->
<property name="map">
<map>
<entry key="Java" value="java"></entry>
<entry key = "Pythom" value="python"></entry>
</map>
</property>
<!-- set集合-->
<property name="sets">
<set>
<value>hello</value>
<value>java</value>
</set>
</property>
<!-- 注入list 对象集合-->
<property name="bookList">
<list>
<ref bean="book1"></ref>
<ref bean="book2"></ref>
</list>
</property>
</bean>
<bean id="book1" class="cn.future.Spring5.Book">
<property name="bAuthor" value="哈姆雷特"></property>
<property name="bName" value="猪头"></property>
</bean>
<bean id="book2" class="cn.future.Spring5.Book">
<property name="bAuthor" value="哈姆雷特"></property>
<property name="bName" value="猪头"></property>
</bean>
</beans>
提取方法
<!-- 提取list集合类型属性注入 -->
<bean id="Stu" class="cn.future.Spring5.Stu">
<property name="bookList">
<ref bean="book"></ref>
</property>
<property name="map">
<ref bean="map"></ref>
</property>
<property name="sets">
<ref bean="set"></ref>
</property>
<property name="list">
<ref bean="list"></ref>
</property>
</bean>
<!-- book list 抽取-->
<util:list id="book">
<ref bean="book1"></ref>
<ref bean="book2"></ref>
</util:list>
<!-- map 抽取 -->
<util:map id="map">
<entry key="Java" value="java"></entry>
<entry key="PytHon" value="python"></entry>
</util:map>
<!-- set抽取 -->
<util:set id="set">
<value>宇猪头</value>
<value>孙猪头</value>
</util:set>
<!-- list抽取 -->
<util:list id="list">
<value>你好</value>
<value>笨蛋</value>
</util:list>
<bean id="book1" class="cn.future.Spring5.Book">
<property name="bName" value="猪"></property>
<property name="bAuthor" value="狗"></property>
</bean>
<bean id="book2" class="cn.future.Spring5.Book">
<property name="bName" value="猪"></property>
<property name="bAuthor" value="狗"></property>
</bean>
4.3 Bean的种类
- 普通bean:在配置文件中定义bean类型就是返回类型
- 工厂bean:在配置文件中定义哦bean类型可以和返回类型不一样
- 第一步 创建类,让这个类作为工厂bean,实现接口factorybean
- 第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型
4.4 Bean的作用域
- 在Spring里面,设置创建bean实例是单实例还是多实例(单实例:创建多次,是同一个对象)
- 在spring里面,设置创建对象为单实例对象
- 如何设置单实例还是多实例
4.5 Bean的生命周期
- 通过构造器创建bean实例(无参数构造)
- 为bean的属性设置值和对其他bean的引用(调用set方法)
- 把bean实例传递bean后置处理器的方法
- 调用bean的初始化的方法(需要进行配置)
- 把bean实例传递bean后置处理器的方法
- bean可以使用了(对象获取到了)
- 当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)
后置处理器
- 定义一个类,实现接口BeanPostProcessor
xml
<bean id = "orders" class="cn.future.bean.Orders" init-method="initMehod">
<property name="oname" value="java"></property>
</bean>
<!-- 配置后置处理器 -->
<bean id="MyBeanPost" class="cn.future.bean.MyBeanPost"></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;
}
}
4.6 xml自动装配
-
什么是自动装配
-
<!-- 自动装配 bean标签属性autowire,配置自动装配 autowire有2个常用值 1) byName:根据属性名注入,注入值bean的id值和类属性名必须一样 2)byType:根据类型注入,相同类型的bean不能定义多个 --> <bean id="Emp" class="cn.future.auto.Emp" autowire="byType"> <!-- 手动装配--> <!-- <property name="dept" ref="Dept"></property>--> </bean> <bean id="dept" class="cn.future.auto.Dept"></bean>
4.7 外部属性文件
4.8 基于注解方式
-
什么是注释
-
Bean管理中创建对象的注解
- @Component
- @Service
- @Controller
- @Repository
-
基于注解方式实现对象的创建
- 第一步:引入依赖 spring-aop-5.2.6.RELEASE.jar
- 第二步:开启组件扫描
- 第三步:创建类,在类上面添加创建注解
-
基于注解方式实现属性注入
-
完全注解开发
五、@Resource和@Autowired
- 都是用来实现自动装配的,都可以放在属性字段上
- @Autowired通过ByType实现自动装配,且要求这个对象必须存在
- @Resource通过ByName实现自动装配,如果找不到名字,通过ByType实现,如果两个都找不到的情况,就报错
- 执行顺序不同,@Autowired通过ByType的方式实现,@Resource通过ByName实现自动装配
六、使用JavaConfig开发
配置类
/**
* @Configuration代表的是一个配置类,就和beans.xml一样
*/
@Configuration
@ComponentScan("com.futureport")
public class Config {
/**
* 注册一个Bean
* 这个方法的名字,就相当于bean标签的id属性
* 这个方法的返回值,就相当于bean标签中的class属性
* @return
*/
@Bean
public User getUser(){
return new User();//返回到要注入bean的对象
}
}
实体类
@Component
public class User {
@Value("hello")
public String name;
}