1.spring IOC基础
1.1.BeanFactory与ApplicationContext区别
BeanFactory:Spring框架中IoC容器的顶层接⼝,SpringIOC的基础容器,它只是⽤来定义⼀些基础功能,定义⼀些基础规范
ApplicationContext:是容器的⾼级接⼝,⽐BeanFactory要拥有更多的功能,⽐如说国际化⽀持和资源访问(xml,java配置类)等等
1.2 spring 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">
</beans>
xmlns="http://www.springframework.org/schema/beans"
声明xml文件默认的命名空间,表示未使用其他命名空间的所有标签的默认命名空间,由于beans是spring ioc基础功能,所以前缀是默认省略的
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
声明XML Schema实例,声明后就可以使用schemaLocation属性。
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
第一个值表示需要使用的命名空间。第二个值表示供命名空间使用的XML schema的位置。
上面配置的命名空间指定xsd规范文件,这样你在进行下面具体配置的时候就会根据这些xsd规范文件给出相应的提示,比如说每个标签是怎么写的,都有些什么属性是都可以智能提示的,在启动服务的时候也会根据xsd规范对配置进行校验
如果要添加其他功能,例如aop,则如下写法
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
...
</beans>
添加 xmlns:aop="http://www.springframework.org/schema/aop" 以及schmaLocation中的
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
命名空间前缀为aop,入后就可以在包裹的范围内使用<aop>标签,当然前缀名也可以取别的,例如aop1等等,只是在使用标签时候会对应的变化
1.3spring IOC容器启动方式
2.spring IOC纯xml模式回顾
2.1.srping IOC容器启动方式
javaSE应用:
// 通过读取classpath下的xml文件来启动容器(xml模式SE应用下推荐)
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
java web应用容器启动:
在web.xml中配置ioc容器以及监听器以及在pom.xml中引入spring web相关功能,
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置Spring ioc容器的配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--使用监听器启动Spring的IOC容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.12.RELEASE</version>
</dependency>
2.2xml模式下实例化bean的三种方式
(1).⽆参构造函数
通过反射调⽤⽆参构造函数来创建对象。如果类中没有⽆参构造函数,将创建失败
<!--Spring ioc 实例化Bean的三种方式-->
<!--方式一:使用无参构造器(推荐)-->
<bean id="connectionUtils" class="com.lagou.edu.utils.ConnectionUtils"></bean>
(2)静态⽅法创建
CreateBeanFactory会提供⼀个创建对象的⽅法,恰好这个⽅法是static修饰的⽅法
<!--另外两种方式是为了我们自己new的对象加入到SpringIOC容器管理-->
<!--方式二:静态方法-->
<bean id="connectionUtils" class="com.lagou.edu.factory.CreateBeanFactory" factory-method="getInstanceStatic"/>
(3)实例化方法创建
和上⾯静态⽅法创建其实类似,区别是⽤于获取对象的⽅法不再是static修饰的了,⽽是
类中的⼀ 个普通⽅法。
<!--方式三:实例化方法-->
<bean id="createBeanFactory" class="com.lagou.edu.factory.CreateBeanFactory"></bean>
<bean id="connectionUtils" factory-bean="createBeanFactory" factory-method="getInstance"/>
2.3 Bean的作用范围与生命周期
在spring框架管理Bean对象的创建时,Bean对象默认都是单例的,可以通过scope来配置不同的作用范围,常用作⽤范围就是singleton(单例模式)和prototype(原型模式,也叫多例模式)
<bean id="transferService"
class="com.lagou.service.impl.TransferServiceImpl" scope="singleton">
</bean>
单例模式:singleton
对象出⽣:当创建容器时,对象就被创建了。
对象活着:只要容器在,对象⼀直活着。
对象死亡:当销毁容器时,对象就被销毁了。
⼀句话总结:单例模式的bean对象⽣命周期与容器相同。
多例模式:prototype
对象出⽣:当使⽤对象时,创建新的对象实例。
对象活着:只要对象在使⽤中,就⼀直活着。
对象死亡:当对象⻓时间不⽤时,被java的垃圾回收器回收了。
⼀句话总结:多例模式的bean对象,spring框架只负责创建,不负责销毁。
2.4 DI 依赖注⼊的xml配置
2.4.1 set⽅法注⼊
set⽅法注⼊:它是通过类成员的set⽅法实现数据的注⼊。(使⽤最多的)示例如下
<!--set注入使用property标签,如果注入的是另外一个bean那么使用ref属性,如果注入的是普通值那么使用的是value属性-->
<property name="ConnectionUtils" ref="connectionUtils"/>
<property name="name" value="zhangsan"/>
<property name="sex" value="1"/>
<property name="money" value="100.3"/>
在使⽤set⽅法注⼊时,需要使⽤ property 标签,该标签属性如下:
name:指定注⼊时调⽤的set⽅法名称。(注:不包含set这三个字⺟,druid连接池指定属性名称)
value:指定注⼊的数据。它⽀持基本类型和String类型。
ref:指定注⼊的数据。它⽀持其他bean类型。写的是其他bean的唯⼀标识
- 复杂数据类型的set方法注入,如下
<property name="myArray">
<array>
<value>array1</value>
<value>array2</value>
<value>array3</value>
</array>
</property>
<property name="myMap">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
</map>
</property>
<property name="mySet">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="myProperties">
<props>
<prop key="prop1">value1</prop>
<prop key="prop2">value2</prop>
</props>
</property>
2.4.2构造函数注⼊
构造函数注⼊:顾名思义,就是利⽤带参构造函数实现对类成员的数据赋值。
<!--name:按照参数名称注入,index按照参数索引位置注入-->
<constructor-arg name="connectionUtils" ref="connectionUtils"/>
<constructor-arg name="name" value="zhangsan"/>
<constructor-arg name="sex" value="1"/>
<constructor-arg name="money" value="100.6"/>
涉及的标签是 constructor-arg ,该标签有如下属性:
name:⽤于给构造函数中指定名称的参数赋值。
index:⽤于给构造函数中指定索引位置的参数赋值。
value:⽤于指定基本类型或者String类型的数据。
ref:⽤于指定其他Bean类型的数据。写的是其他bean的唯⼀标识
3. xml与注解相结合模式
*第三⽅jar中的bean定义在xml,⽐如德鲁伊数据库连接池;⾃⼰开发的bean定义使⽤注解
-
xml中标签与注解的对应(IoC)
image.png
DI依赖注入怎么实现?
(1)@Autowired(推荐使⽤)
@Autowired为Spring提供的注解,需要导⼊包
org.springframework.beans.factory.annotation.Autowired。
@Autowired采取的策略为按照类型注⼊,当⼀个类型有多个bean值的时候,需要配合着@Qualifier使⽤
(2)@Resource
@Resource 注解由 J2EE 提供,需要导⼊包 javax.annotation.Resource。
@Resource 默认按照 ByName ⾃动注⼊
指定了 name,则从上下⽂中查找名称(id)匹配的bean进⾏装配
指定了 type,则从上下⽂中找到类似匹配的唯⼀bean进⾏装配,找不到或是找到多个,
都会抛出异常
3.1 自己开发bean使用注解
如下例子
bean标签对应@Component注解.由于是在service层,所以注解使用@Service("transferService")
ref依赖,原先使用的set方法注入,现在对应注解中的自动装配 @Autowire @Qualifier("accountDao")
</bean>
<bean id="transferService" class="com.lagou.edu.service.impl.TransferServiceImpl">
<!--set+ name 之后锁定到传值的set方法了,通过反射技术可以调用该方法传入对应的值-->
<property name="AccountDao" ref="accountDao"></property>
</bean>
@Service("transferService")
public class TransferServiceImpl implements TransferService {
// 最佳状态
// @Autowired 按照类型注入 ,如果按照类型无法唯一锁定对象,可以结合@Qualifier指定具体的id
@Autowired
@Qualifier("accountDao")
private AccountDao accountDao;
注意:在使用了注解后,注解怎么被框架发现?
用注解后,在xml配置扫描
首先 xml文件头中添加xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
再配置扫描
<!--开启注解扫描,base-package指定扫描的包路径-->
<context:component-scan base-package="com.lagou.edu"/>
**3.2 第三方jar中bean使用xml
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
4.spring IOC 纯注解模式
@Configuration 注解,表名当前类是⼀个配置类
@ComponentScan 注解,替代 context:component-scan
@PropertySource,引⼊外部属性配置⽂件
@Import 引⼊其他配置类
@Value 对变量赋值,可以直接赋值,也可以使⽤ ${} 读取资源配置⽂件中的信息
@Bean 将⽅法返回对象加⼊ SpringIOC 容器
示例如下
// @Configuration 注解表明当前类是一个配置类
@Configuration
@ComponentScan({"com.lagou.edu"})
@PropertySource({"classpath:jdbc.properties"})
/*@Import()*/
public class SpringConfig {
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")
public DataSource createDataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
5.高级特性之Lazy-init
适用范围: singleton bean
默认情况:ApplicationContext 容器启动服务器时将所有 singleton bean 提前进⾏实例化
设置方法:
xml配置
<bean id="testBean" calss="cn.lagou.LazyBean" lazy-init="true" />
注解模式加@Lazy注解即可,默认是开启
使用场景:不常使⽤的 Bean 设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean 就占⽤资源;⼀定程度提⾼容器启动和运转性能
6.高级特性之FactoryBean 和 BeanFactory
BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext
FactoryBeanFactoryBean可以⽣成某⼀个类型的Bean实例,我们可以借助于它⾃定义Bean的创建过程
// 可以让我们⾃定义Bean的创建过程(完成复杂Bean的定义)
public interface FactoryBean<T> {
@Nullable
// 返回FactoryBean创建的Bean实例,如果isSingleton返回true,则该实例会放到Spring容器
的单例对象缓存池中Map
T getObject() throws Exception;
@Nullable
// 返回FactoryBean创建的Bean类型
Class<?> getObjectType();
// 返回作⽤域是否单例
default boolean isSingleton() {
return true;
} }
7.高级特性之后置处理器
未完待续......