@Configuration
之前使用bean.xml配置spring相关配置读取配置的时候
使用注解的时候我们使用配置类来配置spring的相关配置,读取配置如下
配置类中我们配置对应的@Bean注解来把对应的类放到容器中,这样我们就可以通过对应的名称来获取容器中的对象了。
@ComponentScan
这是一个扫描包的注解,配置对应的value属性可以扫描指定包下的所有类,然后把使用了对应注解的类添加到容器中。
其中过滤器有多种属性
使用自定义的过滤器,返回true证明扫到的类可用,false表示不可用
@Scope注解
@Lazy
@Conditional
对应的WindowsCondition.class,linxu差不多
@import
用来向容器中导入类的注解有以下的三种使用方法:
第一种使用方法:直接import 类的class对象
第二种使用方法:使用importselect来导入
第三种:使用使用ImportBeanDefinitionRegistrar
第四种注入bean方法
配置
使用FactoryBean进行容器的注入
1)、默认获取到的是工厂bean调用getObject创建的对象
2)、要获取工程bean本身,我们需要使在默认名称之前加上&,这个是默认的规定
ColorFactoryBean类
之后我们可以看到容器中有了一个叫做colorFactoryBean的对象。我们获取这个对象可以看到这个对象的属性是class com.atguigu.bean.Color
Bean的生命周期
1)、使用@Bean的注解
2)、继承接口
3)、JSR250注解
4)、初始化的前后通知
把继承的类当做组件添加到容器后生效。会在执行实例的初始化方法前后执行对应的操作
一些源码
Spring底层对BeanPostProcess的使用
一堆后置处理器,可以完成很多功能的实现
@Value
可以自动配置属性的值,有三种不同的值配置方式
- 使用基本数值,字符串,int之类的
- 写SpEL表达式:#{}里面可以进行一些简单的运算操作
- 使用${},从环境中获取对应的数据
其中使用${}的时候需要注意,需要先把对应的配置文件导入才可以进行自动配置。在xml文件中导入的办法
在配置文件中导入的方法需要使用@PropertiesSource 来实现,他是一个可以重复使用的注解,可以配置多个
@PropertiesSource
如上所示,用来获取配置文件的一个注解
当我们把配置放到了环境中。可以通过注解获取到也可以通过环境来获取到对应的注解属性
@Autowired
以下为个人理解
使用@Autowired自动注入的时候,会先去容器中按照类型获取对应的类,来注入到对应的位置。
但是如果存在多个相同类型的bean那么就会根据一定的规则来选择bean
如果我们想要自己控制注入的类型的id使用@Qualifier来完成,
使用@Primary可以告诉容器这个bean是优先级比较高的一个。优先使用带有@Primary的。使用之后也可以使用@Qualifier,但是@Qualifier优先级比@Primary高
@Autowired可以标注的位置
- 标注在方法位置:
- 可以标注在普通类的普通方法上,这样如果方法有参数,参数在容器中存在就会自动注入
- 普遍使用是和@Bean使用,被bean注解的方法,如果有参数,会自动从容器中寻找对应的方法,而且不用写@Autowired注解
- 标注在构造方法上:
- 如果组件只有一个构造方法,那么这个有参构造方法可以不写@Autowired会自动从容器中获取。
- 如果有多个的话,和普通方法一样,会自动从容器中找到对应的类型注入
- 放在参数位置上
- 字面意思。无需多言
@Resource和其他的自动注入类
在bean中获取底层组件
@Profile
spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能
开发环境,测试环境,生产环境
数据源:(/A)(/B)(/C);
示例一:使用虚拟机配置启动环境
启动之后发现只有对应的环境下的数据源可以被获取到
示例二:配置激活环境
使用
原理
AOP原理:@EnableAspectJAutoProxy入手
流程:
1、创建IOC容器
2、注册配置类,然后调用refresh方法。刷新容器
3、refresh刷新,注册的bean的后置处理器来拦截bean创建:
3.1先获取IOC容器已经定义的需要创建对象的所有BeanPost
1.@EnableAspectJAutoProxy
- @EnableAspectJAutoProxy 通过@Import(AspectJAutoProxyRegistrar.class)给spring容器中导入了一个AnnotationAwareAspectJAutoProxyCreator。
- AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor是一个BeanPostProcessor。它可以拦截spring的Bean初始化(Initialization)前后和实例化(Initialization)前后。
- AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation(bean实例化前):会通过调用isInfrastructureClass(beanClass)来判断 被拦截的类是否是基础类型的Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),若是则放入adviseBean集合。这里主要是用来处理我们的切面类。
- AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessorsAfterInitialization(bean初始化后):
- 首先找到被拦截的Bean的匹配的增强器(通知方法),这里有切入点表达式匹配的逻辑
- 将增强器保存到proxyFactory中,
- 根据被拦截的Bean是否实现了接口,spring自动决定使用JdkDynamicAopProxy还是ObjenesisCglibAopProxy
- 最后返回被拦截的Bean的代理对象,注册到spring容器中
- 代理Bean的目标方法执行过程:CglibAopProxy.intercept();
- 保存所有的增强器,并处理转换为一个拦截器链
- 如果没有拦截器链,就直接执行目标方法
- 如果有拦截器链,就将目标方法,拦截器链等信息传入并创建CglibMethodInvocation对象,并调用proceed()方法获取返回值。proceed方法内部会依次执行拦截器链。
1、使用
1.导入相关依赖
数据源,数据库驱动,spring-jdbc模块
2.配置数据源。。JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
3.给方法上标注@Transactional表示当前方法是一个事务方法
4.@EnableTransactionManagement开启基于注解的事务管理功能
5.配置事务管理器来控制事务
2、原理
@EnableTransactionManagement上有一个注解会给容器导入一个TransactionManagementConfigurationSelector对象,来进行一些组件的导入
TransactionManagementConfigurationSelector源码如下:
实导入两个组件
AutoProxyRegistrar.class
ProxyTransactionManagementConfiguration.class
AutoProxyRegistrar干什么的
继承了注册bean的接口,给容器中注册了一个InfrastructureAdvisorAutoProxyCreator类
InfrastructureAdvisorAutoProxyCreator是做什么的:
利用后置处理器机制在对象创建一后,包装对象,返回一个代理器对象,代理对象执行方法利用拦截器执行对象。
ProxyTransactionManagementConfiguratio干什么的
给容器中利用bean注册各种组件:
- 事务增强器:
- 事务注解器:要用事务注解的信息AnnotationTransactionAttributeSour接卸事务的注解
- 事务拦截器:TransactionInterceptor保存了事务属性信息,事务管理器。他是一个MethodInterceptor方法拦截器。在目标方法执行的时候执行拦截器链。
- 事务拦截器功能
- 先获取事务属性,再去获取PlatformTransactionManager
- 如果出现异常获取事务,回滚,没有异常获取事务提交
- 事务拦截器功能
1.BeanFactoryPostProcessor
- BeanPostProcessor是Bean后置处理器:bean创建初始化前后进行拦截工作
- BeanFactoryPostProcessor是Bean工厂后置处理器:
- 在BeaanFactory标准初始化之后进行调用:所有bean定义已经保存加载到beanFactory,但是Bean的实例还没有创建
1)、IOC容器创建对象
2)、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors
- 如何找到所有的BeanFactoryPostProcessor并执行它们的方法
- 1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcess的组件,并执行它们的方法。
- 2)、在初始化其他组件前面执行。
2.BeanDefinitionRegistryPostProcessor
执行方法:postProcessBeanDefinitionRegistry
在所有Bean定义信息将要被加载,bean实例还没有被创建的时候。
这里类的执行顺序比BeanFactoryPostProcessor执行的早,并且可以在这个类中注册bean信息。给容器中添加一些组件。
原理:
- 1、IOC创建对象
- 2、调用刷新方法()-》invokeBeanFactoryPostProcessors(beanFactory);
- 3、先从容器中获取到所有的BeanDefinitionRegistrayPostProcessor组件。
- 依次除法所有的postProcessBeanDefinitionRegistry()方法
- 之后再触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
- 4、再来从容器中找到BeanFactoryPostProcessor组件,依次除法postProcessBeanFactory()方法。
ApplicationListener:监听容器中发布的事件。事件驱动模型的开发
ContextRefreshedEvent:容器刷新事件
ContextClosedEvent:容器死掉事件
步骤:
1、写一个事件监听器来监听某个事件(ApplicationEvent及其子类)
2、把监听器加入到容器中
3、只要容器中有相关事件的发布,我们就能监听到这个事件爱你:
4、发布一个事件:
1)、ContextRefreshedEvent事件;
- 1、容器创建对象的时候会调用refresh方法
- 2、finishRefresh()最后的刷新,调用了一个publicEvent(new ContextRefresh())方法
- 【事件发布流程】
- 1.获取到事件的多播器(派发器)getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
- multicastEvent:事件派发。
- 获取到所有的ApplicationListener
- for (ApplicationListener<?> listener : getApplicationListeners(event, type))
- 如果有Executor可以支持使用Executor进行异步派发。
- 否则同步的方式直接执行listener方法。拿到listener回掉onApplicationEvent方法;
- 【事件发布流程】
- 3、容器关闭也会添加一个容器关闭事件。
【事件多播器】(事件派发器)
1、容器创建对象。refresh();
2、initApplicationEventMulticaster();ApplicationEventMulticaster;
- 先去容器中找有没有id="applicatinEventMulticaster"的组件
- 如果没有程序就用自己新建的simpleapplictionEventMulticaster,并加入到容器中,我们就可以在其他组件派发事件的时候自动注入applicationEventMulticaster
【容器中有哪些监听器】
1)、容器创建对象:refresh();
- .registerListeners();
从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中:
string[] listenerBeanNlmes = getBeanNamesForType(ApplicationListener.class,true, false)
//将listener注册到ApplicationEventMulticaster中
getApplicationEventMulticaster( ) . addApplicationListenerBean(listenerBeanName);
注解开发
使用@EventListener来进行注解开发
原理:
SmartInitializingSingleton
- 1.ioc容器创建对象并refresh()
- 2.finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
- 先创建所有的单实例bean;getBean();
- 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的
- 如果是就调用afterSingletonsInstantiated()
3.Sping容器创建过程
Spring容器的创建和刷新refrsh()[创建刷新]
1、prepareRefresh();预处理工作
- 1、initPropertySources()初始化一些属性设置。留给子类来做事情的。子类自定义个性化的属性设置方法
- 2、getEnvironment().validateRequiredProperties();进行属性校验,校验属性和发等等
- 3、earlyApplicationEvents = new LinkedHashSet<>(); 保存容器中的一些早期的事件
2、obtainFreshBeanFactory();获取beanfactory;
- 1、refreshBeanFactory()刷新工厂
- 创建了一个this.beanFactory = new DefaultListableBeanFactory();
- 设置id
- 2、getBeanFactory()返回了工厂;
- 3、将beanfactory返回DefaultListableBeanFactory
3、prepareBeanFactory(beanFactory):BeanFactory的预准备工作(BeanFactory进行一些设置)
- 1、设置Beanfactory的类加载器、支持表达式解析器。
- 2、添加部分BeanPostProcessor[ApplicaitonContextAwareProcessor]
- 3、配置忽略的自动装配的接口EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware
- 4、registerResolvableDependency注册可以解析的自动装配。我们能直接在任何组建中自动装配的部分
- 5、beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));添加许多的后置处理器
- 6、添加编译时的Aspect支持;
- 7、非beanFactory中注册一些能用的组件
- environment[ConfigurableEnvironment]
- systemProperties
4、postProcessBeanFactory(beanFactory);BeanFactory准备工作
=BeanFactory以及预准备工作===========
5、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors
- BeanFactoryPostProcessors:BeanFactory的后置处理器,在BeanFactory标准初始化之后执行的
- 两个接口:BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor
- 执行BeanFactoryPostProcessor方法
- 1、获取所有的BeanDefinitionRegistryPostProcessor;
- 2、看优先级排序PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor/postProcessor.postProcessBeanDefinitionRegistry(registry)
- 3、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
- postProcessor.postProcessBeanDefinitionRegistry(registry)
- 4、最后执行没有实现任何优先级或者是顺序接口的
- BeanDefinitionRegistryPostProcessors;postProcessor.postProcessBeanDefinitionRegistry(registry)
- 再执行BeanFactoryPostProcessor方法
- 1、获取所有的BeanFactoryPostProcessor
- 之后方法大致和上面相同
- 执行BeanFactoryPostProcessor方法
6、registerBeanPostProcessors(beanFactory);执行BeanPostProcessors,Bean的后置处理器【拦截bean创建过程】
不同类型的BeanPostProcessor:在Bean创建前后的执行时机是不一样的
BeanPostProcessor:
DestructionAwareBeanPostProcessor:
InstantiationAwareBeanPostProcessor:
SmartInstantiationAwareBeanPostProcessor:
MergedBeanDefinitionPostProcessor:【internalPostProcessors】
- 1、String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);获取所有的beanPostProcessor;后置处理器都默认可以有优先级
- 2、先注册PriorityOrered优先级接口的BeanPostProcessor
- 把每一个BeanPostProcessor添加到BeanFactory中
- 3、再来注册Ordered接口的
- 4、最后注册的没有实现任何优先级接口的
- 5、最终注册MergedBeanDefinitionPostProcessor
- 6、注册一个ApplicationListenerDatector:来在Bean创建完成后检查是否ApplicationListener,如果是
- applicationcontext.addApplicationListener((ApplicationListener<?>) bean);
7、initMessageSource();初始化MessageSource组件(做国际化功能消息绑定。消息解析)
- 1、获取BeanFactory
- 2、容器中是否为id为messagesource组件,没有就整一个默认的messagesource
- 如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource:
- MessageSource:取出估计花配置文件中的某个key的值。
- 如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource:
- 3、把创建好的MessageSource注册在容器中,以后获取国际化标准配置文件的值得时候,可以自动驻入MessageSource;
- beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME,this.messageSource);
- MessageSource.getMessage(String code,Object[] args,String defaultMessage,Local…)
8、initApplicationEventMulticaster();初始化事件派发器
- 1、获取BeanFactory
- 2、从BeanFactory中获取ApplicationEventMulticaster的
- 3、没有配置就自动创建SimpleApplicationEventMulticaster
- 4、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接注入
9、onRefresh();初始化剩下的bean,留给子类的
- 1、子类重写这个方法。在容器刷新的时候自定义做其他的事情。
10、registerListeners();
- 1、从容器中拿到所有的ApplicationListener组件
- 2、将每个监听器添加到事件派发器中
- getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
- 3、派发之前步骤产生的事件。
11、finishBeanFactoryInitialization(beanFactory);初始化所有单实例的bean
- 1、beanFactory.preInstantiateSingletons();初始化所有单实例的bean
- 1、获取容器中的所有bean,依次进行初始化和创建对象。
- 2、获取bean定义信息RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
- 3、如果!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
- 判断是否是isFactoryBean(beanName);是否实现了FactoryBean
- 如果不是工厂getBean(beanName);
- 1、getBean(beanName);ioc.getBean()
- 2、doGetBean(name,null,null,false)
- 3、先获取缓存中保存的单实例bean.如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
- 从private final Map<String,object> singleton0bjects
- 4、缓存中获取不到,开始Bean的创建流程
- 5、标记当前bean已经创建
- 6、获取当前Bean依赖的其他bean
- 7、启动单实例bean的创建流程
- 1、createBean(beanName,mbd,args);
- 2、Object bean = resolveBeforeInstantiatino(beanName,mbdToUse);让beanpost提前拦截返回代理对象;
- InstantiationAwareBeanPostProcessor:提前执行;
- 先触发:postProcessBeforeInstantiation()
- 如果有返回值:触发postProcessAfterInitialization
- 3、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象
- 4、doCreateBean()创建一个bean实例
- 1、创建bean实例CreateBeanInstance
- 解析bean类型。利用工厂方法,或者对象构造器,创建出bean实例。
- 2、applyMergedBeanDefinitionPostProcessors(mbd, beanType,beanName);
- 调用MergedBeanDefinitionPostProcessor bdp.postProcessMergedBeanDefinition(mbd, beanType,beanName) ;
- 3、【Bean属性赋值populateBean(beanName,mbd, instancewrapper);
- 1、赋值之前判断到InstantiationAwareBeanPostProcessor后置处理器;执行postProcessAfterInstantiation方法
- 2、拿到InstantiationAwareBeanPostProcessor后置处理器
- postProcessPropertyProcessor
- 赋值之前:==========
- 3、applyPropertyvalues( beanName,mbd,bw, pvs) ;应用bean属性的值。
- 4、【bean】初始化initializeBean( beanName, exposedobject, mbd);
- 1、invokeAwareMethods(beanName, bean);执行Aware接口的方法
- BeanNameAwareBeanclaswareBeanFactorvAwarer
- 2、【执行】applyBeanPostProcessorsBeforeInitialization
- BeanPostProcessor.postProcessBeforeInitialization
- 3、执行初始化方法invokeInitMethods(beanName,wrappedBean,mbd);
- 1、是否是InitializingBean接口的实现;
- 2、是否自定义初始化方法;
- 4、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization
- BeanPostProcessor.postProcessAfterInitialization()
- 5、注册Bean的销毁方法;
- 1、invokeAwareMethods(beanName, bean);执行Aware接口的方法
- 5、将创建的Bean添加到缓存中singletonObjects;
- ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。
- 1、创建bean实例CreateBeanInstance
- 所有Bean都利用getBean创建完成以后;
- 检查所有的Bean是否是SmartInitializingSingleton接口的,如果是,就执行afterSingletonsInstant
- 12、finishRefresh()完成初始化创建工作。IOC容器创建完成
-
- 、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
写一个LifecycleProcessor的实现类,可以在BeanFactory
void onRefresh();
void onclose();
- 、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
- 2)、getLifecycleProcessor( ).onRefreshO;
- 拿到前面定义的生命周期处理器(BeanFactory)﹔回调
-
- . publishEvent(new ContextRefreshedEvent(this));发布
- 4)、veBeansview.registerApplicationcontext(this);
-
总结
1、spring容器在启动的时候会保存所有注册进来的Bean定义信息
2、Spring容器在合适的时机创建这些bean
3、后置处理器:
4、事件驱动模型:
- 用户发送请求至前端控制器。
- 前端控制器收到请求调用处理器映射器。
- 处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器,一并返回给前端控制器。
- 前端控制器调用处理器适配器,处理器适配器经过适配调用具体的处理器(controller,也叫后端控制器)。
- controller 执行完成返回 ModelAndView。
- 处理器适配器将 controller 执行结果 ModelAndView 返回给 前端控制器。
- 前端控制器将 ModelAndView 传给 视图解析器。
- 视图解析器解析后返回 VIew。
- 前端控制器根据 View 进行渲染视图(将模型数据填充至页面)。
- 前端控制器响应给用户。
● 原理:利用预编译的机制将sql语句的主干和参数分别传输给数据库。
● JDBC中使用PreparedStatement可以防止sql注入。
● mybatis中提供了两种方式:#{} 和 ${}、
● #{}: 在预处理时,会把参数部分作为一个占位符 ? 代替。能有效解决sql注入问题。
● ${}: 表示拼接字符串,并将接受的内容不加修饰符拼接到sql中,将会引起sql注入问题。
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/jjc/67453.html