文章目录
Component是最最基础的注解。表示这是一个Bean 可以被注入到Spring container里。
其他三个就是Spring的经典三层layer了
@Controller @Service @Repository
(控制层)表现层 表示此类专注于对前端请求进行转发和重定向
业务逻辑层:处理业务逻辑
持久层:DAO类 表示此类专注于对数据库进行数据的读取或者写入。
这三个注解表示了三个基本任务:处理前端请求 处理业务逻辑 处理数据库读写。
1 组件注册
AnnotationConfigApplicationContext
配置类
//配置类=配置文件
@Configuration //告诉Spring这是一个配置类
//排除规则 指定扫描的时候按照什么规则排除那些组件 excludeFilters = Filter[] 排除注解类型FilterType.ANNOTATION
@ComponentScan(value = "com.zt" , excludeFilters = {@Filter(type = FilterType.ANNOTATION , classes = {Controller.class, Service.class})})
public class MainConfig {
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Bean("person") //指定名字
public Person getPerson(){
return new Person("lisi",20);
}
}
@Configuration
//包含规则 指定扫描的时候只需要包含哪些组件 includeFilters = Filter[]
//useDefaultFilters = false 禁用默认的过滤规则
@ComponentScan(value = "com.zt" ,
includeFilters = {@Filter(type = FilterType.ANNOTATION ,
classes = {Controller.class, Service.class})},useDefaultFilters = false)
public class MainConfig {
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Bean("person") //指定名字
public Person getPerson(){
return new Person("lisi",20);
}
}
@Configuration //告诉Spring这是一个配置类
//@ComponentScans 包含多个ComponentScan规则
@ComponentScans(value = {
@ComponentScan(value = "com.zt" ,
includeFilters = {@Filter(type = FilterType.ANNOTATION ,
classes = {Controller.class, Service.class})},useDefaultFilters = false)
})
public class MainConfig {
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
@Bean("person") //指定名字
public Person getPerson(){
return new Person("lisi",20);
}
}
测试类:
public class IocTest {
@SuppressWarnings("resource")
@Test
public void test1(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
过滤规则
//FilterType.ANNOTATION : 按照注解方式
@Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class}
//FilterType.ASSIGNABLE_TYPE : 按照指定的类型 BookService的子类或者实现类都能被包含其中
@Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}
//FilterType.ASPECTJ : 使用ASPECTJ表达式
//FilterType.REGEX : 使用正则表达式
//FilterType.CUSTOM : 使用自定义规则 必须是TypeFilter的实现类
@Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class}
public class MyTypeFilter implements TypeFilter {
//metadataReader : 读取到的当前正在扫描的类的信息
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源信息(类的路径等)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println(className);
if (className.contains("er"))
return true;
return false;
}
}
@Scope 作用域
调整作用域
prototype:多实例的 :IOC容器启动并不会调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象。
singleton :单实例的(默认值)。 IOC容器启动会调用方法创建对象放在IOC容器,以后每次获取就是直接从容器(map.get())中拿
request:同一次请求创建一次
session:同一个session创建一个实例
@Configuration
public class MainConfig02 {
//默认是单实例 无论是获取多少次都是同一个对象
@Bean("person")
//prototype:多实例的 singleton :单实例的(默认值) request:同一次请求创建一次 session:同一个session创建一个实例
@Scope("prototype")
public Person person(){
return new Person("张三",25);
}
}
@Lazy Bean懒加载
单例Bean:默认在容器启动的时候创建对象;
懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
@Configuration
public class MainConfig02 {
@Bean("person")
@Lazy
public Person person(){
return new Person("张三",25);
}
}
@Conditional
按照一定的条件进行判断,满足条件给容器中注册Bean。
可以配置在类和方法上。注解后面跟上相关配置条件。
配置类
//满足当前条件,这个类中配置的所有bean注册才能生效
@Conditional({WindowsCondition.class})
@Configuration
public class MainConfig02 {
//默认是单实例 无论是获取多少次都是同一个对象
@Bean("zhang")
//prototype:多实例的 singleton :单实例的(默认值) request:同一次请求创建一次 session:同一个session创建一个实例
@Scope("prototype")
public Person person(){
return new Person("张三",25);
}
@Conditional({LinuxCondition.class})
@Bean("li")
public Person person01(){
return new Person("李四",15);
}
//@Conditional 传递的是Condition数组
@Conditional({WindowsCondition.class})
@Bean("wang")
public Person person02(){
return new Person("王五",35);
}
}
自定义判断条件一:
//判断是否是Linux系统
public class LinuxCondition implements Condition {
//conditionContext 判断条件能使用的上下文(环境)
//annotatedTypeMetadata 注解信息
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//能获取到IOC使用的BeanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取到类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取环境信息
Environment environment = conditionContext.getEnvironment();
//获取到bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
//可以判断容器中的bean注册情况,也可以给容器中注册bean
boolean definition = registry.containsBeanDefinition("person");
String name = environment.getProperty("os.name");
// System.out.println(name);
if (name.contains("linux")){
return true;
}
return false;
}
}
自定义判断条件2:
//判断是否是Windows系统
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String name = environment.getProperty("os.name");
if (name.contains("Windows")){
return true;
}
return false;
}
}
测试类:
@Test
public void test3(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig02.class);
ConfigurableEnvironment environment = context.getEnvironment();
//动态获取环境变量的值
String osName = environment.getProperty("os.name");
System.out.println(osName);
String[] names = context.getBeanNamesForType(Person.class);
for (String name : names) {
System.out.println(name);
}
Map<String, Person> beans = context.getBeansOfType(Person.class);
System.out.println(beans);
}
输出结果:
Windows 10
zhang
wang
{zhang=Person{name=‘张三’, age=25}, wang=Person{name=‘王五’, age=35}}
2 组件注入
给容器中注册组件
- 包扫描+组件标注注解(@Controller / @Service / @Repository / @Component)局限于是自己写的类
- @Bean 导入的第三方包里面的组件
- @Import 快速给容器中导入一个组件
a. @Import(要导入的容器) 容器中就会自动注册这个组件,id默认是全类名。可以批量导入(写的是数组)
b. ImportSelector:返回需要导入的组件的全类名数组,进行批量导入
c. ImportBeanDefinitionRegistrar : 手动注册bean到容器中 - 使用Spring提供的FactoryBean(工厂Bean)
a. 默认获取到的是工厂Bean调用getObject创建的对象
b. 要获取工厂Bean本身,我们要在给id前面加一个&
2.1 @Import
配置类
@Configuration
//导入组件,id默认是组件的全类名 直接使用@import导入需要spring4.2以上版本,不然会报错
//@Import(Color.class)
@Import({Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig021 {
}
ImportBeanDefinitionRegistrar实现类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
//AnnotationMetadata 当前类的注解信息
//BeanDefinitionRegistry:BeanDefinition注册类;
// 把所有需要添加到容器中bean 调用
// BeanDefinitionRegistry.registerBeanDefinition 手工注册
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
boolean definition = beanDefinitionRegistry.containsBeanDefinition("com.zt.bean.Blue");
boolean definition1 = beanDefinitionRegistry.containsBeanDefinition("com.zt.bean.Yellow");
if (definition && definition1){
//指定bean定义信息(Bean的类型,Bean 的作用域等)
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//注册一个bean
beanDefinitionRegistry.registerBeanDefinition("rainRow",beanDefinition);//指定bean名
}
}
}
ImportSelector实现类
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
//返回值就是导入到容器中的组件全类名
//AnnotationMetadata : 当前标注@Import 注解的类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//方法不要返回null值,否则会报空指针异常
return new String[]{"com.zt.bean.Blue","com.zt.bean.Yellow"};
}
}
测试类
@Test
public void test4(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig021.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
Map<String, Person> beans = context.getBeansOfType(Person.class);
System.out.println(beans);
}
测试结果:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig021
com.zt.bean.Red
com.zt.bean.Blue
com.zt.bean.Yellow
rainRow
{}
2.2 FactoryBean
工厂Bean
//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {
//返回一个Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean...");
return new Color();
}
@Override
public Class<?> getObjectType() {
return Color.class;
}
//是否是单例
//true : 这个bean是单实例,在容器中保存一份
//false : 多实例,每次获取都会创建一个新的bean
@Override
public boolean isSingleton() {
return true;
}
}
配置类
@Configuration
//导入组件,id默认是组件的全类名 直接使用@import导入需要spring4.2以上版本,不然会报错
//@Import(Color.class)
@Import({Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig021 {
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}
测试类
@Test
public void test5(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig021.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//工程Bean获取的是调用getObject创建的对象
Object colorFactoryBean = context.getBean("colorFactoryBean");
System.out.println("bean的类型:"+colorFactoryBean.getClass());
//要获取工厂Bean本身,我们要在给id前面加一个&
Object colorFactoryBean1 = context.getBean("&colorFactoryBean");
System.out.println("bean的类型:"+colorFactoryBean1.getClass());
}
3 生命周期
Bean的生命周期:
Bean创建 — 初始化 — 销毁的过程
容器来管理Bean的生命周期。
我们可以自定义初始化和销毁的方法;容器在Bean 进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
构造(对象创建)
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
对象创建完成,并赋值好,调用初始化方法
销毁:
单实例:容器关闭的时候销毁Bean
多实例:容器不会管你这个Bean;容器不会调用销毁方法。需要手动销毁
指定初始化和销毁方法:
通过@Bean指定init-method和destroy-method
Bean类
public class Car {
public Car() {
System.out.println("Car constructor...");
}
public void init(){
System.out.println("Car ... init ...");
}
public void destroy(){
System.out.println("Car ... destroy ...");
}
}
配置类
@Configuration
public class MainConfigOfLifeCycle {
@Scope("prototype")
@Bean(initMethod = "init" , destroyMethod = "destroy")
public Car car(){
return new Car();
}
}
测试类
@Test
public void test6(){
//创建IOC容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//关闭容器
context.close();
}
输出结果:
Car constructor…
Car … init …
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigOfLifeCycle
car
Car … destroy …
通过让Bean实现InitializingBean(定义初始化逻辑)、DisposableBean(定义销毁逻辑)
Bean类
@Component
public class Cat implements InitializingBean , DisposableBean {
public Cat() {
System.out.println("Cat constructor ...");
}
//销毁
@Override
public void destroy() throws Exception {
System.out.println("Cat destroy ...");
}
//初始化
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Cat init ...");
}
}
配置类
@ComponentScan("com.zt.bean")
@Configuration
public class MainConfigOfLifeCycle {
}
测试类
@Test
public void test7(){
//创建IOC容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//关闭容器
context.close();
}
十月 28, 2021 2:42:12 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1c6b6478: startup date [Thu Oct 28 14:42:12 CST 2021]; root of context hierarchy
Cat constructor …
Cat init …
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigOfLifeCycle
cat
十月 28, 2021 2:42:13 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1c6b6478: startup date [Thu Oct 28 14:42:12 CST 2021]; root of context hierarchy
Cat destroy …
JSR250
@PostConstruct:在Bean 创建完成并且属性赋值完成;来执行初始化
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
Bean类
@Component
public class Dog {
public Dog() {
System.out.println("Dog constructor ...");
}
//对象创建并赋值之后调用
@PostConstruct
public void init(){
System.out.println("Dog ... @PostConstruct ... init ...");
}
//容器移除对象之前
@PreDestroy
public void destroy(){
System.out.println("Dog ... @PreDestroy ... destroy ...");
}
}
配置类
@ComponentScan("com.zt.bean")
@Configuration
public class MainConfigOfLifeCycle {
}
测试方法
@Test
public void test7(){
//创建IOC容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//关闭容器
context.close();
}
输出结果:
十月 28, 2021 2:54:37 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1c6b6478: startup date [Thu Oct 28 14:54:37 CST 2021]; root of context hierarchy
Cat constructor …
Cat init …
Dog constructor …
Dog … @PostConstruct … init …
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigOfLifeCycle
cat
dog
十月 28, 2021 2:54:37 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1c6b6478: startup date [Thu Oct 28 14:54:37 CST 2021]; root of context hierarchy
Dog … @PreDestroy … destroy …
Cat destroy …
BeanPostProcessor接口—后置处理器(重点)
Bean的后置处理器;
在Bean初始化前后进行一些处理工作
postProcessBeforeInitialization : 在初始化之前工作
postProcessAfterInitialization : 在初始化之后工作
BeanPostProcessor 的原理
populateBean(beanName,mbd,instanceWrapper); //给Bean进行属性赋值
//initializeBean
{
//遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
//一旦返回null,就跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
applyBeanPostProcessorsBeforeInitialization(warppedBean,BeanName);
invokeInitMethods(beanName,wrappedBean,mbd); 执行自定义初始化
applyBeanPostProcessorsAfter Initialization(warppedBean,BeanName);
}
Spring底层对BeanPostProcessor的使用
Bean赋值、注入其他组件、@Autowired、声明周期注解功能、@Async等等,都是由BeanPostProcessor完成的。有不同的PostProcessor进行处理。
BeanPostProcessor实现类
@Component
//后置处理器:初始化前后进行处理
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessBeforeInitialization... beanName is "+s+" bean is "+o);
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessAfterInitialization... beanName is "+s+" bean is "+o);
return o;
}
}
测试方法
@Test
public void test7(){
//创建IOC容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//关闭容器
context.close();
}
输出(主要):
postProcessBeforeInitialization… beanName is cat bean is com.zt.bean.Cat@971d0d8
Cat init …
postProcessAfterInitialization… beanName is cat bean is com.zt.bean.Cat@971d0d8
Dog constructor …
postProcessBeforeInitialization… beanName is dog bean is com.zt.bean.Dog@c8e4bb0
Dog … @PostConstruct … init …
postProcessAfterInitialization… beanName is dog bean is com.zt.bean.Dog@c8e4bb0
4 组件赋值
使用@Value 进行赋值
1.基本数值
2.可以写SpEL;#{}
3.可以写 ${}; 取出配置文件【properties】中的值(在运行环境变量里边的值)
Bean类
public class Person {
/*使用@Value 进行赋值
* 1.基本数值
* 2.可以写SpEL;#{}
* 3.可以写${};取出配置文件【properties】中的值(在运行环境变量里边的值)*/
@Value("San Zhang")
private String name;
@Value("#{20-2}")
private Integer age;
//要取出外边配置文件的值 必须在xml文件中配置<context:property-placeholder location= "cLasspath :person.properties"/>
@Value("${person.nickName}")
private String nickName;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Person(String name, Integer age, String nickName) {
this.name = name;
this.age = age;
this.nickName = nickName;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", nickName='" + nickName + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
}
配置类
//使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中
@PropertySource(value = "classpath:/person.properties")
@Configuration
public class MainConfigOfPropertyValues {
@Bean
public Person person(){
return new Person();
}
}
配置文件
person.nickName=Small San Zhang
测试方法
@Test
public void test8(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
Person person = context.getBean(Person.class);
System.out.println(person);
ConfigurableEnvironment environment = context.getEnvironment();
String property = environment.getProperty("person.nickName");
System.out.println("person.nickName: "+property);
}
输出结果:
mainConfigOfPropertyValues
person
Person{name=‘San Zhang’, age=18, nickName=‘Small San Zhang’}
person.nickName: Small San Zhang
5 自动装配
自动装配:Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值
5.1 @Autowired 自动注入
属性注入
-
默认优先按照类型去容器中找对应的组件:
applicationContext.getBean(BookDao.class); -
如果找到多个相同类型的组件,再将属性的名称作为组件的ID去容器中查找:
applicationContext.getBean(“bookDao1”); -
@Qualifier(“bookDao”) 指定需要装配的组件ID,而不是使用属性名
BookService{
@Qualifier("bookDao")
@Autowired(required=false)
private BookDao bookDao1;
}
-
自动装配一定要将属性赋值好,如果容器中没有指定的类,就会报错。可以指定@Autowired(required=false)避免报错。
-
@Primary:让Spring进行自动装配的时候,默认使用首选的Bean。也可以使用@Qualifier来指定需要装配的Bean的名字。
构造器、参数、方法注入、@Bean
标注在方法上,Spring容器创建当前对象,就会调用方法,完成赋值
方法使用的参数,自定义类型的值从IOC容器中获取
都是从容器中获取
-
方法注入
标注在方法上,Spring容器创建当前对象,就会调用方法,完成赋值方法使用的参数,自定义类型的值从IOC容器中获取
//默认加在IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
@Component
public class Boss {
private Car car;
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
public Car getCar() {
return car;
}
//标注在方法上,Spring容器创建当前对象,就会调用方法,完成赋值
//方法使用的参数,自定义类型的值从IOC容器中获取
@Autowired
public void setCar(Car car) {
this.car = car;
}
}
- 构造器注入
构造器要用的组件,是从容器中获取
如果组件只有一个有参构造器,这个有参构造器的 @Autowired 可以省略,参数位置的组件还是可以自动从容器中获取。
//默认加在IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
@Component
public class Boss {
private Car car;
//构造器要用的组件,都是从容器中获取
@Autowired //可以省略
public Boss(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
}
- 参数注入
参数要用的组件,也是容器中获取
//默认加在IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
@Component
public class Boss {
private Car car;
public Boss(@Autowired Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
public Car getCar() {
return car;
}
//标注在方法上,Spring容器创建当前对象,就会调用方法,完成赋值
//方法使用的参数,自定义类型的值从IOC容器中获取
// @Autowired
public void setCar(Car car) {
this.car = car;
}
}
- @Bean 标注的方法创建对象的时候,方法参数的值是从容器中获取
@Bean
public Color color(Car car){
return new Color();
}
5.2 @Resource(JSR250) , @Inject(JSR330) [Java规范的注解]
@Resource:可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配
但是没有支持@Primary和@Autowired(required=false)的功能
BookService{
@Resource(name = "bookDao") //可以通过指定name来进行注入
private BookDao bookDao1;
}
@Inject:和@Autowired的功能一样,但是比@Autowired少一个required=false的功能
需要导入一个依赖
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
5.3 三者区别
@Autowired是由Spring定义的;而@Resource和@Inject是Java规范
AutowiredAnnotationBeanPostProcessor :解析完成自动装配功能;
6 自定义组件实现xxxAware(获得Spring容器底层组件)
自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx)
自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件。
把Spring底层一些组件注入到自定义的Bean;
xxxAware都是由xxxAwareProcessor来处理的。
例如ApplicationContextAware 是由ApplicationContextAwareProcessor来处理的。ApplicationContextAwareProcessor则是BeanPostProcessor的实现类。注入组件是由xxxAwareProcessor中的invokeAwareInterfaces(Object bean) 方法来实现注入的。
@Component
public class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("传入的IOC:" + applicationContext);
}
@Override
public void setBeanName(String s) {
System.out.println("当前Bean的名字"+s);
}
@Override
public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
String resolveStringValue = stringValueResolver.resolveStringValue("系统名称是 ${os.name} 能够计算20*18=#{20*18}");
System.out.println("解析的字符串:"+resolveStringValue);
}
}
6.1 @Profile
指定组件在哪个环境的情况下才能被注册到容器中。如果不指定@Profile,任何环境下都能注册这个组件
以数据源为例,先导入数据源
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
写在Bean上的@Profile
加了环境标识@Profile的Bean,只有在这个环境被激活的时候才能被注册到容器中。默认是Default环境。
配置类
/*Profile :
* Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
*
* 一个项目中一般有:开发环境、测试环境、生产环境
* 数据源:(/A) (/B) (/C)*/
@Configuration
@PropertySource("classpath:/jdbc_config.properties")
public class MainConfigOfProfile implements EmbeddedValueResolverAware {
@Value("${db.user}")
private String user;
private String driverClass;
@Profile("test")
@Bean
public Yellow yellow(){
return new Yellow();
}
//测试数据源
@Profile("test")
@Bean("testDataSource")
public DataSource dataSourceTest(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setDriverClass(driverClass);
return dataSource;
}
//开发数据源
@Profile("dev")
@Bean("devDataSource")
public DataSource dataSourceDev(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
dataSource.setDriverClass(driverClass);
return dataSource;
}
//生产数据源
@Profile("prod")
@Bean("prodDataSource")
public DataSource dataSourceProd(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/prod");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
driverClass = stringValueResolver.resolveStringValue("${db.driverClass}");
}
}
测试方法:
//使用命令行动态参数 在虚拟机参数位置加载 -Dspring.profiles.active=dev
//代码方式
@Test
public void test11(){
//创建一个ApplicationContext对象 此处需要调用无参构造器,如果调用有参构造器的话会直接启动容器,无法进行中间配置
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//设置需要激活的环境 可一次性设置多个
context.getEnvironment().setActiveProfiles("test","dev");
//注册主配置类
context.register(MainConfigOfProfile.class);
//启动刷新容器
context.refresh();
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
写在类上的@Profile
写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
@Profile("test")
@Configuration
public class MainConfigOfProfile{
}
7 AOP 动态代理
指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;
三步:
1)、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
2)、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
3)、开启基于注解的aop模式;
AOP示例
- 导入AOP模块,Spring AOP
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.12</version>
- 定义一个业务逻辑类(spring-aspects);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)
public class MathCalculator {
public int div(int i , int j){
return i/j;
}
}
- 定义一个日志切面类;切面类里面的方法需要动态感知MathCalculator.div 运行到哪里然后执行
public class LogAspects {
public void logStart(){
System.out.println("除法运行...参数列表是:{}");
}
public void logEnd(){
System.out.println("除法结束...");
}
public void logReturn(){
System.out.println("除法正常返回...计算结果是:{}");
}
public void logException(){
System.out.println("除法异常...异常信息是:{}");
}
}
通知方法:
前置通知(@Before):logStart;在目标方法(div)运行之前运行
后置通知(@After):logEnd;在目标方法(div)运行结束之后运行。无论方法正常结束还是异常结束,都调用
返回通知(@AfterReturning):logReturn;在目标方法(div)正常返回之后运行
异常通知(@AfterThrowing):logException;在目标方法(div)出现异常之后运行
环绕通知(@Around):动态代理,手动 推进目标方法运行(joinPoint.procced( ))
- 给切面类的目标方法标注何时何地运行(通知注解)
public class LogAspects {
//抽取公共的切入点表达式
//本类引用 @Before("pointCut()")
//其他类引用 @Before("com.zt.aop.LogAspects.pointCut()")
@Pointcut("execution(public int com.zt.aop.MathCalculator.*(..))")
public void pointCut(){}
//@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
@Before("pointCut()") //public int com.zt.aop.MathCalculator.div(int,int)
public void logStart(JoinPoint joinPoint){ // JoinPoint 必须放在参数的第一位
Object[] args = joinPoint.getArgs();
System.out.println(joinPoint.getSignature().getName()+"运行...参数列表是:{"+ Arrays.asList(args) +"}");
}
@After("pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName()+"结束...");
}
@AfterReturning(value = "pointCut()",returning = "result")
public void logReturn(Object result){
System.out.println("除法正常返回...计算结果是:{"+result+"}");
}
@AfterThrowing(value = "pointCut()",throwing = "e")
public void logException(Exception e){
System.out.println("除法异常...异常信息是:{"+e+"}");
}
}
- 将切面类和业务逻辑类(目标方法所在类)都加入到容器中
@Configuration
public class MainConfigOfAOP {
//业务逻辑类加入到容器中
@Bean
public MathCalculator mathCalculator(){
return new MathCalculator();
}
//切面类加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
- 必须告诉Spring哪个类是切面类(给切面类上加一个注解 @Aspect )
@Aspect
public class LogAspects
- 给配置类中加@EnableAspectJAutoProxy【开启基于注解的AOP模式】
在Spring中由很多的@EnableXXX;用于开启某一项功能来替代之前的配置
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {}
- 测试方法
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
MathCalculator calculator = applicationContext.getBean(MathCalculator.class);
System.out.println(calculator.div(10, 2));
applicationContext.close();
}
输出结果:
div运行…参数列表是:{[10, 2]}
MathCalculator…div…
div结束…
除法正常返回…计算结果是:{5}
5
AOP原理
AOP流程
bean = applyBeanPostProcessorsBeforeInstantiation();
//拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor ;就执行postProcessBeforeInstantiation
if(bean!=null){
bean = applyBeanPostProcessorsAfterInstantiation();
}
AnnotationAwareAspectJAutoProxyCreator的作用
AOP总结
8 声明式事务
事务实现流程
环境搭建:
- 导入相关依赖
数据源、数据库驱动、Spring-jdbc模块
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
- 配置数据源、JdbcTemplate操作数据库
配置类
@PropertySource("classpath:/jdbc_config.properties")
@Configuration
public class TxConfig {
@Value("${db.user}")
private String user;
@Value("${db.password}")
private String password;
@Value("${db.driverClass}")
private String driverClass;
@Value("${db.url}")
private String url;
//数据源
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setDriverClass(driverClass);
return comboPooledDataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
//Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件|
//JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
}
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void insert(){
String sql = "insert into `tbl_user`(username,age) values(?,?)";
String name = UUID.randomUUID().toString().substring(0, 5);
jdbcTemplate.update(sql,name,19);
}
}
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void insert(){
userDao.insert();
}
}
测试方法:
@Test
public void test12(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class);
UserService service = context.getBean(UserService.class);
service.insert();
}
-
给方法上标注@Transactional表示当前方法是一个事务方法;
-
@EnableTransactionManagement 开启基于注解的事务管理功能;
@EnableXXX 类似的注解都是实现某一项功能的 -
配置事务管理器来控制事务: public PlatformTransactionManager transactionManager(DataSource dataSource)
@PropertySource("classpath:/jdbc_config.properties")
@Configuration
@EnableTransactionManagement
public class TxConfig {
@Value("${db.user}")
private String user;
@Value("${db.password}")
private String password;
@Value("${db.driverClass}")
private String driverClass;
@Value("${db.url}")
private String url;
//数据源
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setDriverClass(driverClass);
return comboPooledDataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
//Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件|
//JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
//注册事务管理器在容器中
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}
事务原理
从上所述,事务底层就是AOP实现的,before里面开启事务,affter提交事务。affterthrowing回滚事务
9 扩展原理
BeanFactoryPostProcessor
-
BeanPostProcessor: bean后置处理器,bean创建 对象初始化前后进行拦截工作的
-
BeanFactoryPostProcessor: beanFactory的后置处理器;
beanFactory 标准初始化之后调用;所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
int count = configurableListableBeanFactory.getBeanDefinitionCount();
String[] names = configurableListableBeanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+"个Bean 分别是 "+ Arrays.asList(names));
}
}
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
postProcessBeanDefinitionRegistry();
在所有bean定义信息将要被加载,bean实例还未创建的;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor...postProcessBeanFactory...");
}
//BeanDefinitionRegistry 是Bean定义信息的保存中心,
//以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建Bean实例
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor...postProcessBeanDefinitionRegistry...");
// RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("hello",beanDefinition);
}
}
优先于BeanFactoryPostProcessor执行; 利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件;
ApplicationListener
//监听容器中发布的事件。完成事件驱动模型开发;
public interface ApplicationListener<E extends ApplicationEvent>
步骤
1)、 写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)或用注解@EventListener
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
// 当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("收到时间:"+applicationEvent);
}
}
@Service
public class UserService {
@EventListener(classes = {ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService...监听到的事件"+event);
}
}
2)、把监听器加入到容器;
3)、只要容器中有相关事件的发布,我们就能监听到这个事件;
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
ContextClosedEvent:关闭容器会发布这个事件;
4)、发布一个事件:
@Test
public void test(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件
context.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
context.close();
}
SmartInitializingSingleton
10 Spring容器创建过程
源码:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();//重点关注这个方法
}
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();//刷新前的预处理工作
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); //获取BeanFactory
this.prepareBeanFactory(beanFactory);//BeanFactory的预处理设置(beanFactory进行一些设置)
try {
this.postProcessBeanFactory(beanFactory);//BeanFactory准备工作完成后进行的后置处理工作;
this.invokeBeanFactoryPostProcessors(beanFactory);//执行BeanFactoryPostProcessor
this.registerBeanPostProcessors(beanFactory);//注册BeanPostProcessors(注册Bean的后置处理器)
this.initMessageSource();//初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
this.initApplicationEventMulticaster();//初始化事件派发器
this.onRefresh();//留给子容器(子类 )子类可以重写这个方法,在容器刷新的时候可以自定义逻辑;
this.registerListeners();//给容器中将所有项目里面的ApplicationListener注册进来
this.finishBeanFactoryInitialization(beanFactory);//初始化所有剩下的单实例bean
this.finishRefresh();//完成BeanFactory的初始化创建工作。IOC容器就创建完成
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
prepareRefresh();//刷新前的预处理工作
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (this.logger.isInfoEnabled()) {
this.logger.info("Refreshing " + this);
}
this.initPropertySources();//初始化一些属性设置 方法中为空 留给子类处理
this.getEnvironment().validateRequiredProperties();//属性校验
this.earlyApplicationEvents = new LinkedHashSet(); //保存容器中的一些早期的事件
}
obtainFreshBeanFactory();//获取BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();//刷新BeanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
prepareBeanFactory(beanFactory);//BeanFactory的预处理设置(beanFactory进行一些设置)
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
invokeBeanFactoryPostProcessors(beanFactory);//执行BeanFactoryPostProcessor
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
invokeBeanFactoryPostProcessors -> PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
Iterator var6 = beanFactoryPostProcessors.iterator();
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors = new ArrayList();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var18 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var18 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var21 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var28 = 0; var28 < var10; ++var28) {
String ppName = var21[var28];
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var22 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var22; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var23 = orderedPostProcessorNames.iterator();
while(var23.hasNext()) {
String postProcessorName = (String)var23.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var26 = currentRegistryProcessors.iterator();
while(var26.hasNext()) {
ppName = (String)var26.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
registerBeanPostProcessors(beanFactory);//注册BeanPostProcessors(注册Bean的后置处理器)
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<BeanPostProcessor> internalPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
List<String> nonOrderedPostProcessorNames = new ArrayList();
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
initMessageSource();//初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("messageSource")) {
this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(this.getInternalParentMessageSource());
}
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using MessageSource [" + this.messageSource + "]");
}
} else {
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(this.getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton("messageSource", this.messageSource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate MessageSource with name 'messageSource': using default [" + this.messageSource + "]");
}
}
}
initApplicationEventMulticaster();//初始化事件派发器
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
}
}
}
registerListeners();//给容器中将所有项目里面的ApplicationListener注册进来
protected void registerListeners() {
Iterator var1 = this.getApplicationListeners().iterator();
while(var1.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
String[] var7 = listenerBeanNames;
int var3 = listenerBeanNames.length;
for(int var4 = 0; var4 < var3; ++var4) {
String listenerBeanName = var7[var4];
this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
Iterator var9 = earlyEventsToProcess.iterator();
while(var9.hasNext()) {
ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishBeanFactoryInitialization(beanFactory);//初始化()实例化所有剩下的单实例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
public String resolveStringValue(String strVal) {
return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
}
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
}
finishRefresh();//完成BeanFactory的初始化创建工作。IOC容器就创建完成
protected void finishRefresh() {
this.initLifecycleProcessor();
this.getLifecycleProcessor().onRefresh();
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
原理
总结
11 Web
12 SpringMVC异步请求
结果:
是主线程告诉副线程,我先去忙别的了,你执行好了叫我顺便把结果给我,我或者我的一个兄弟再拿着结果去响应数据
下面看一个实际场景:
请求创建订单——>应用1 但是实际创建订单是需要应用2完成,这里使用到消息中间件 ,应用2监听消息,有请求创建并返回
请求创建订单:
在3秒后返回消息,有消息就返回deferredResult,没有的话返回后面的提示信息
栗子:
定义一个队列,存储信息:
createorder为创建订单请求,在3秒内监听队列,有值的话返回,没有的话返回提示信息。
create为创建订单的实际方法,创建订单并存储队列。
成功返回!