IOC容器
控制反转,把对象创建和对象之间的调用过程都交给Spring进行管理,降低代码之间的耦合。
底层原理
xml解析、对象工厂、反射
- xml配置文件,配置创建的对象
- 创建工厂类,通过xml解析获得类的class属性
- 通过forName获取Class对象
- 通过Class的newInstance进而创建xml配置的对象
接口(BearFactory、ApplicationContext)
二者功能相似
(一)、BearFactory
IOC容器基本实现,是spring内部使用的接口
- 加载配置文件的时候不会创建对象,在获取(使用)对象才会去创建对象
(二)、ApplicationContext
是BearFactory的子接口
- 加载配置文件的时候就会把配置文件中的对象创建(慢启动,快响应)
操作Bean管理
- Spring创建对象
- Spring注入属性
xml
(一)创建对象:
-
创建对象 < bean id="" class=""/ >
id:给对象取别名(唯一标识)
class:类全路径(包类路经)
name:可以加特殊符号(一般不使用) -
创建对象时默认使用无参构造
(二)注入属性:
DI:依赖注入(DI是IOC的一种实现)
设置一个null值:< null/ >
属性值包含特殊符号:CDATA
< ![CDATA[“特殊符号”]]>
- set方法注入
<bean ...>
<!--
name:类里面属性名称
value:向属性注入的值
-->
<property name="" valur=""></property>
</bean>
- 有参构造注入
<bean ...>
<constructor name="" valur=""></constructor>
</bean>
- p命名空间
1、添加p命名空间在配置文件中xmlns:p=“http://www.springframework.org/schema/p”
2、进行属性注入,在bean中
<bean ... p:bname="" p:bautor=""></bean>
- 外部bean
-ref注入外部bean - 内部bean
<bean id="emp" class="com.zhanggoudan.spring5.bean.Emp">
<property name="ename" value="lucy"></property>
<property name="gender" value="nv"></property>
<property name="dept">
<bean id="dept" class="com.zhanggoudan.spring5.bean.Dept">
<property name="dname" value="anbao"></property>
</bean>
</property>
</bean>
- 级联复制
<bean id="emp" class="com.zhanggoudan.spring5.bean.Emp">
<property name="ename" value="lucy"></property>
<property name="gender" value="nv"></property>
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.zhanggoudan.spring5.bean.Dept">
<property name="dname" value="caiwu"></property>
</bean>
(三)注入属性-集合:
1、List结构:array,list,set
2、Map结构:map,entry,props,prop
只要结构相同,标签可互换
<bean id="stu" class="com.zhanggoudan.Stu">
<property name="courses">
<array>
<value> aaa </value>
<value> bbb </value>
</array>
</property>
<property name="list">
<list>
<value> ccc </value>
<value> ddd </value>
</list>
</property>
<property name="maps">
<map>
<entry key="AAA" value="aaa"></entry>
<entry key="BBB" value="bbb"></entry>
</map>
</property>
<property name="sets">
<set>
<value>MySql</value>
<value>PHP</value>
</set>
</property>
</bean>
(四)引入命名空间util:(提取属性)
xmlns:util="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--提取list集合类型属性注入-->
<util:list id="AAA">
<value></value>
</util:list>
<!--提取list集合类型属性注入使用-->
<bean id="" class="">
<property name="" ref="AAA"></property>
</bean>
自动装配
- 根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
- bean标签属性autowire配置自动装配
- byName 根据属性名称注入:注入值bean的id值和类属性名称必须一致
- byType根据属性类型注入:相同类型的bean不能定义多个
引入外部属性文件
-
直接配置数据库信息
(1)、配置德鲁伊连接池 -
引入外部属性文件配置数据库连接池
(1)、创建外部属性文件,写入属性信息
(2)、把外部properties属性文件引入到spring配置文件中–>context名称空间
(3)、配置文件中使用标签引入外部属性文件
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${prop.url}" />
<property name="username" value="${prop.userName}" />
<property name="password" value="${proo.password}" />
<property name="driverClassName" value="${prop.diverClass}" />
</bean>
${}中填入.properties里等号左侧值
注解
- 注解是代码中的特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…)
- 注解可以作用在类、属性、方法上
- 可以简化xml配置
创建对象
- @Component(通用)
- @Service(Service层)
- @Controller(Web层)
- @Repository(Dao层)
四个注解功能是相同的
1、引入AOP依赖
2、开启组件扫描:
(1)、引入context命名空间
(2)、如果扫描多个包可用逗号隔开,或直接扫描包的上层目录
<context:component-scan base-package="com.zhanggoudan,com.Dao"></context:component-scan>
<context:component-scan base-package="com"></context:component-scan>
(3)、使用注解
//注解里面的value属性值可以省略
//默认值是类名称,首字母小写
@Component(value = "userService")
public class UserService
3、组建扫描的细节
<!--示例 1
use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
context:include-filter ,设置扫描哪些内容
-->
<context:component-scan base-package="com.atguigu" use-defaultfilters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--示例 2
下面配置扫描包所有内容
context:exclude-filter: 设置哪些内容不进行扫描
-->
<context:component-scan base-package="com.atguigu">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
属性注入
- @AutoWired:根据属性类型进行自动装配
(一)把service和dao对象创建,在service和dao类中添加创建对象注解
(二)在service中注入dao对象,在service类添加dao类型属性,在属性上面使用注解
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void add(){
}
}
- @Qualifier:根据属性名称进行注入
要与@Autowired一起使用,根据名称注入
-
@Resource:可以根据类型注入,也可以根据名称注入
-
@Value:注入普通类型属性
@Value(value="abc")
private String name;
完全注解开发
(1)创建配置类,替代 xml 配置文件
@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages ={"com.atguigu"})
public class SpringConfig {
}
(2)编写测试类
@Test
public void testService2() {
//加载配置类
ApplicationContext context
=new AnnotationConfigApplicationContext(SpringConfig.class);
FactoryBean
- Spring有两种类型Bean,一种是普通bean,另外一种工厂bean(FactoryBean)
- 普通bean:在配置文件中定义bean类型就是返回类型
- 工厂bean:在配置文件中定义bean类型可以跟返回类型不一样
让类继承FactoryBean接口,实现方法中getObject可以定义返回类型
bean的作用域
- 在Spring里面,设置创建bean实例是单实例还是多实例
- 在Spring中,默认情况下bean是单实例对象
scope属性值
1、singleton,单实例对象(默认值)
2、prototype,多实例对象
singleton在加载配置文件时,就会创建实例对象
prototype在调用getBean方法时,才会创建多实例对象
bean的生命周期
- 通过构造器创建bean的实例(无参构造)
- 为bean的属性设置值和对其他bean的引用(调用set方法)
- bean的初始化的方法(需要进行配置)
- bean可以使用了(获取到对象)
- 当容器关闭时候,调用bean的销毁方法(需要进行配置)
加入后置处理器声明周期变为七步:
第三步前后加入步骤—>把bean实例传递bean后置处理器的方法
让类实现BeanPostProcessor接口
第三步之前:postProcessBeforeInitialization
第三步之后:postProcessAfterInitialization