| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Spring IOC注解笔记(杂) -> 正文阅读 |
|
[Java知识库]Spring IOC注解笔记(杂) |
写在前面本文是笔者自己在学习SpringIOC注解时的随堂笔记,仅作备份查阅用,不具备可阅读学习性(跑 一、组件注册1.1 @Configuration在没配置@ComponentScan的情况下,默认只扫描和主类处于同包下的Class。 平时创建bean用的配置方法:beans.xml
现在创建一个配置类:@Configuration 用@bean来创建bean
1.2 @ComponentScan里的Filter来条件扫包@AliasFor 是为了属性起别名 为什么要给 value 属性和 path 属相互相设置别名也是有原因的。我们知道在 Spring 中给 value 属性设置值是可以省略属性的,比如可以写成:@RequestMapping("/foo") 这样写比较简洁,但是这样可读性不高,我们并不知道 value 属性代表什么意思。如果给这个属相设置一个 path 别名的话我们就知道这个是在设置路径。 但是要注意一点,@AliasFor 标签有一些使用限制:
FilterType各自种类。FilterType.ANNOTATION标志按照注解进行包含排除,后面传需要排除或包含的注解类,如:Controller.class ASSIGNABLE_TYPE:按照给定类型 classes={BookService.class} REGEX:使用正则表达式 ASPECTJ: CUSTOM:自定义过滤规则:需要一个实现TypeFilter接口的类,接口定义的方法里的参数可以获取到一些信息。 ? 自定义Filter 获取注解、类路径等信息 1.3 @Scope作用域默认单实例(singleton) singleton、prototype、request、session request:同一次请求创建一个实例 session:同一个session创建一个实例 1.4 @Lazy懒加载懒加载:容器启动不创建对象,第一次调用(获取)Bean的时候再创建对象 懒加载是一种取巧办法,容器调用getBeanDefinitionNames方法或者getBean等要用到Bean的的时候,才会创建对象 1.5 @Conditional 条件注册Bean@Conditional 可以放在类或方法上 放在方法上 单个bean 类上就是整个类的bean是否注册 @Contional注解 条件注册bean 传入一个实现了Conditional接口的类 其方法里的参数:ConditionContext context可以获取到beanFactory、Classloader、environment、registry等 然后可以根据不同的环境来判断这个bean是否需要注册。
在VM Options,可以修改os.name的值 1.6 @Import导入Bean
1.7 FactoryBean组件注册Bean(工厂Bean)实现FactoryBean接口,泛型为你要的bean。注意这里是FactoryBean不是BeanFactory FactoryBean的特殊之处在于它可以向容器中注册两个Bean,一个是它本身,一个是FactoryBean.getObject()方法返回值所代表的Bean。 在我们通过FactoryBean的实现类获得具体bean的时候,会调用getObject方法来返回其创建的泛型对象。 所以如果我们需要FactoryBean实现类的bean,就需要,加一个& 如
还有一个isSingleton来让getObject返回的是否单例对象。 Spring 有一个factorybean 与其他框架联动用的很多 工厂模式 Spring使用工厂模式可以通过 二、生命周期Bean销毁: ? 如果Bean是单实例:容器关闭的时候 ? 如果Bean是多实例:容器不会管理这个Bean,不会调用销毁方法(GC来?试了一下System.gc()好像也不行),不过会调用Bean的init方法(如果有) 所以:Spring IOC容器中只存放单例Bean https://developer.51cto.com/art/202104/660312.htm 2.1 @Bean注解指定初始化和销毁方法Bean注解内的方法
通过在Bean注解里标注User里的方法(initUser、destoryUser)
2.2 实现InitializingBean和DisposableBean接口Spring会自动识别类是否实现了这两个接口,实现了就调用他们的方法。 InitializingBean接口的方法:
DisposableBean接口的方法:
2.3 @PostConstruct和@PreDestroy注解 (JSR250Spring会自动识别类中的方法是否标注了这两个注解,标注了就调用他们的方法。
2.4 【重点】BeanPostProcessor接口可以创建一个自定义类实现BeanPostProcessor接口,如MyBeanPostProcessor 注意:这个自定义类需要注册到IOC容器中(可以@Component标记类)
postProcessBeforeInitialization:在Bean 初始化(init)之前工作 postProcessAfterInitialization:在Bean 初始化(init)之后工作 Spring中实现了BeanPostProcessor 接口的一些接口: ApplicationContextAware接口:传入ioc容器——底层:ApplicationContextAwareProcessor类会在bean init前判断Bean是否实现了*.Aware接口,如果有,就调用一些方法传入东西 BeanValidationPostProcessor类:实现了BeanPostProcessor 接口的预设类,实现了postProcessBeforeInitialization和postProcessAfterInitialization方法,里面的doValidate(bean);会在init前后对数据进行校验 InitDestoryAnnotationBeanPostProcessor类:让@PostConstruct、@PreDestroy注解生效。找到标注了生命周期注解的方法并且利用反射invoke它们 Spring底层对BeanPostProcessor的使用: ? bean赋值,注入到其他组件,@Autowired,生命周期注解功能,@Async,xxx都是用BeanPostProcessor来完成的 这是自己搞得 initUserWithAnno方法是实现init方法的其中一种(本文2.3) 同理destory 下图主要来理解不同方法的调用时期(BeanPostProcessor接口提供围绕每个bean的init调用的前后钩子函数) BeanPostProcessor源码populateBean是为属性赋值 applyBeanPostProcessorsBeforeInitialization方法: 三、属性赋值3.1 @Value赋值以前用配置文件为bean赋值的方式:
因为IOC容器只管理单例bean,所以直接在实体类中对着实体类@Value()进行赋值 注解里可以填写的内容:
3.2 @PropertySource加载外部配置文件以前xml配置的时候
现在直接用@PropertySource注解:(哪个实体类要用配置文件,可以直接加在实体类上,或者直接在配置类文件上加注解)
或者可以在配置类上加,配合ComponentScan扫注解的时候环境里一样有配置加载进来
applicationcontext.getEnvironment()的getProperty方法
四、自动装配自动装配:Spring利用依赖注入(DI),完成对IOC容器中各个组件依赖关系的赋值 4.1 @Autowired&@Qualifier&@Primary@Autowired:默认是byType方式,如果匹配不上,就会byName 如果byName找不到就会报错:解决:配合@Qualifer(“指定具体name”)
**@Autowired默认容器中有这个bean ,没有就会报错;**这个注解有required = flase 就不需要强制要求这个bean了 如果有bean被@Primary修饰,而且@Autowired没有配合@Qualifier明确指定,那么同类型下被@Primary修饰的bean会被赋值 如果既有@Primary,又有@qualifer,那么会去装配@Qualifer指定的那个bean 4.2 @Resource@Resource:默认是byName方式,如果匹配不上,就会byType 相比@Autowired缺点:没有支持@Primary功能和required属性
@Autowired:Spring定义的;@Resource、@Inject都是java规范 AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能的PostProcessor 4.3 方法、构造器位置的@Autowired@Autowired的Target有构造器、参数、方法、属性 标在方法上: 标在构造器上(如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取 @Bean标注的方法创建对象的时候,方法参数的值从容器中获取,可以省略@Autowired @Autowired不管标注在哪儿,都是从容器中获取bean 不用记这么细,反正到时候根据报错提示来复习 4.4 【重点】 Aware注入Spring底层组件&原理Aware接口:用于想使用spring底层对象的接口 可以创建一个类实现ApplicationContextAware、BeanNameAware、EmbeddedValueResolverAware(解析String中的#{} ${}) xxxAware接口功能:使用xxxProcessor传入 【重点】 如:ApplicationContextAware ==> ApplicationContextAwareProcessor populateBean ->initializeBean ? ->applyBeanPostProcessorsBeforeInitialization ->invokeInitMethods ->applyBeanPostProcessorsAfterInitialization ? ->getBeanPostProcessors().postProcessBeforeInitialization ? ->invokeAwareInterfaces 4.5 @Profile环境搭建(略)@Profile Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能 开发环境、测试环境、生产环境 比如根据数据源来切换(这里以c3p0为例) @PropertySource 来导入数据库的配置文件 多种注入方式体验1.@Value( k e y ) 2. 实 现 E m b e d d e d V a l u e R e s o l v e r A w a r e 接 口 用 V a l u e R e s o l v e r 来 r e s o l v e S t r i n g V a l u e ( {key}) 2.实现EmbeddedValueResolverAware接口用ValueResolver来resolveStringValue( key)2.实现EmbeddedValueResolverAware接口用ValueResolver来resolveStringValue({key}) 4.6 配合@Profile,根据环境注册bean@Profile(“xxxxx”) xxxx是指自定的环境名称标识 ,可以作用在类上,也可以作用在方法上 加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中 默认激活@Profile(“default”) 没有标注的bean,在任何环境下都会被加载 激活环境方法:
附:有参的ApplicationContext代码(2.就是参照了这个手动调用的)
toString使用错误导致OOM我改写toString 上面return this 想打印@来判断是否同一个bean,结果造成了oom 原因:toString方法中打印的其他对象的toString会间接循环,导致你的方法一直在调用方法,且没有返回,每次调用导致栈上升,最后导致栈溢出,所以在使用toString方法时需要注意到递归问题,不要造成了死递归。 后面解决,把this改成super.toString()就好了 其实本质是 ioc还有一个三级缓存解决循环依赖的问题没讲 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:51:54- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |