文章目录
一 常用配置类
1.@Bean和@Configuration
@Bean用来给容器注入一个组件。默认为单实例,可通过@Scope修改
@Configuartion标注这是一个配置类。
1.1 基本使用
写一个配置类
@Configuration
public class personConfig {
//方法名作为bean的ID,配置的在容器中的person的ID为:person01
@Bean
public person person01()
{
return new person("12","Czy");
}
}
要注入容器中的类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class person {
public String age;
public String name;
}
打印获取的类
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
//根据Bean的ID获取,
person person=(person) annotationConfigApplicationContext.getBean("person01");
//查看Bean的类型
System.out.println("id为person01的Bean类型为------>" + person.getClass());
//打印获取到的数据
System.out.println(person);
}
}
输出为:
id为person的Bean类型为------>class com.czy.Entity.person
person(age=12, name=Czy)
1.2 改变注入容器中的Bean的ID值
一般情况下,方法名为bean的ID值,如在@Bean直接添加(value=”__“),则可以改变Bean的ID值
例如做出如下改动
@Bean("person02")
public person person01()
{
return new person("12","Czy");
}
则person在容器中的ID值会改为person02
2.@ComponentScan
给配置类加上@ComponentScan,其中value值为包的路径,配置类会自动将该包下的标注了诸如(@Controller,@Autowired,@Service,@Repository,@Compoent)的类自动转注进容器中。
2.1 具体用法
项目的目录结构如下,Controller包和Service包下的都添加了注解
配置类添加注解@ComponentScan
@Configuration
@ComponentScan("com.czy")
public class personConfig {
@Bean("person02")
public person person01()
{
return new person("12","Czy");
}
}
获取到的bean如下:(可见标注了@Controller,@Autowired,@Service,@Repository,@Compoent已经自动注入到容器中)
当前获取到的bean的ID为personConfig
当前获取到的bean的ID为peroController
当前获取到的bean的ID为mainApplication
当前获取到的bean的ID为personService
2.2 @ComponentScan深入使用
①扫描时排除注解标注的类
Filter[] excludeFilters() default {};
具体设置代码如下
/*
* type:指定你要排除的规则,FilterType.ANNOTATION按照注解进行排除
* classes:除了@Controller和@Service标注的组件之外,IOC容器中剩下的组件我都要,即相当于是我要排除@Controller和@Service这俩注解标注的组件。
*/
@Filter(type=FilterType.ANNOTATION, classes={Controller.class, Service.class})
FilterType 有如下几种方式
public enum FilterType {
/**
* Filter candidates marked with a given annotation.
* @see org.springframework.core.type.filter.AnnotationTypeFilter
*/
ANNOTATION,
/**
* Filter candidates assignable to a given type.
* @see org.springframework.core.type.filter.AssignableTypeFilter
*/
ASSIGNABLE_TYPE,
/**
* Filter candidates matching a given AspectJ type pattern expression.
* @see org.springframework.core.type.filter.AspectJTypeFilter
*/
ASPECTJ,
/**
* Filter candidates matching a given regex pattern.
* @see org.springframework.core.type.filter.RegexPatternTypeFilter
*/
REGEX,
/** Filter candidates using a given custom
* {@link org.springframework.core.type.filter.TypeFilter} implementation.
*/
CUSTOM
}
FilterType 取ASSIGNABLE_TYPE的话,扫描Entity下的类时,该类不需要加@Component就可以向容器中注入。
如果不取 ASSIGNABLE_TYPE的话,则只能
如下代码,Snake不需要加@Component就能注入到容器中
@Configuration
@ComponentScan(value="com.czy.Entity",includeFilters = {@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,classes= {Snake.class, MyBeanPostProcessor.class})},useDefaultFilters = false)
public class personConfig {
@Scope("prototype")
@Bean(value="person02",initMethod = "init",destroyMethod = "destory")
public person person01()
{
return new person("12","Czy");
}
}
② 扫描时只扫描包含注解标注的类
Filter[] includeFilters() default {};
@ComponentScan(value="com.czy", excludeFilters={
/*
* type:指定你要排除的规则,FilterType.ANNOTATION按照注解进行排除
* classes:除了@Controller和@Service标注的组件之外,IOC容器中剩下的组件我都要,即相当于是我要排除@Controller和@Service这俩注解标注的组件。
* useDefaultFilters需要设置为false,才可以根据自己的设定进行扫描
*/
@Filter(type=FilterType.ANNOTATION, classes={Controller.class, Service.class})
}, useDefaultFilters=false)
③ 自定义过滤规则
要实现自定义规则进行过滤时,自定义规则的类必须是org.springframework.core.type.filter.TypeFilter接口的实现类。
具体代码实现如下:
自己写一个实现类实现org.springframework.core.type.filter.TypeFilter接口。
以下代码将类名中含有Service的类加入容器中,其他的类不加入容器。
public class FilterImplement implements TypeFilter {
/**
* 参数:
* metadataReader:读取到的当前正在扫描的类的信息
* metadataReaderFactory:可以获取到其他任何类的信息的(工厂)
* 返回值为True则成功,否则失败:失败不会加入容器中,成功才加入容器
*/
@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("Service"))
return true;
return false;
}
}
则输出结果只有:
当前获取到的bean的ID为personConfig//配置类
当前获取到的bean的ID为personService//通过自定义过滤器添加的组件
当前获取到的bean的ID为person02//通过Bean添加的组件
3.@Scope
@Scope用于设置Bean的创建方式:单实例/多实例
源码如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
/**
* Alias for {@link #scopeName}.
* @see #scopeName
*/
@AliasFor("scopeName")
String value() default "";
/**
* Specifies the name of the scope to use for the annotated component/bean.
* <p>Defaults to an empty string ({@code ""}) which implies
* {@link ConfigurableBeanFactory#SCOPE_SINGLETON SCOPE_SINGLETON}.
* @since 4.2
* @see ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
* @see #value
*/
@AliasFor("value")
String scopeName() default "";
/**
* Specifies whether a component should be configured as a scoped proxy
* and if so, whether the proxy should be interface-based or subclass-based.
* <p>Defaults to {@link ScopedProxyMode#DEFAULT}, which typically indicates
* that no scoped proxy should be created unless a different default
* has been configured at the component-scan instruction level.
* <p>Analogous to {@code <aop:scoped-proxy/>} support in Spring XML.
* @see ScopedProxyMode
*/
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
可知scopeName可以有以下的取值(类名#类中的属性):
①ConfigurableBeanFactory#SCOPE_PROTOTYPE:singleton:单实例的(默认值)
②ConfigurableBeanFactory#SCOPE_SINGLETON:prototype:多实例的
③org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST:request:同一请求创建一个实例
④org.springframework.web.context.WebApplicationContext#SCOPE_SESSION:同一个Session创建一个实例
ConfigurableBeanFactory的部分源码为:
单实例创建会在Ioc容器启动后自动创建,以后每次获取的bean都会是同一个Bean。
多实例创建则会在getBean方法的时候才回去创建Bean实例,且每次创建的Bean都不一样。
具体使用方法如下:
@Scope("prototype")
@Bean("person02")
public person person01()
{
return new person("12","Czy");
}
验证:
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
//根据Bean的ID获取,
person person=(person) annotationConfigApplicationContext.getBean("person02");
//根据Bean的ID获取,
person person1=(person) annotationConfigApplicationContext.getBean("person02");
System.out.println(person == person1);
}
结果如下:
15:26:28.055 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'personConfig'
15:26:28.060 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'personService'
15:26:28.073 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Found key 'spring.liveBeansView.mbeanDomain' in PropertySource 'systemProperties' with value of type String
false
4.@Lazy
如果想让单实例Bean在初始化容器时不自动创建,而是在获取的时候才创建,可以使用@Lazy。
具体用法如下:在方法上添加
@Configuration
@ComponentScan(value="com.czy",includeFilters = {@ComponentScan.Filter(type= FilterType.CUSTOM,classes= {FilterImplement.class})},useDefaultFilters = false)
public class personConfig {
@Lazy
// @Scope("prototype")
@Bean("person02")
public person person01()
{
return new person("12","Czy");
}
}
5.@Conditional
作用:按照一定的条件进行判断,满足添加才给容器中添加注册Bean
@Conditonal的源码如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition Conditions} that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
可知value需要传入实现Condtion接口的类,同时可知它可以标注在
①方法上,则方法要创建Bean需要满足Condtional的条件才行。
②类上,则类要满足Condtional的条件才能实现里面的所有创建Bean的方法。
具体使用代码实现:
实现场景:当系统使用的系统为Windows时,注册Bean,否则不注册
配置类如下:
@Configuration
@ComponentScan(value="com.czy",includeFilters = {@ComponentScan.Filter(type= FilterType.CUSTOM,classes= {FilterImplement.class})},useDefaultFilters = false)
public class personConfig {
//根据源码,value值填入的类必须实现Condition接口
@Conditional(value = {Windows.class})
@Bean("person02")
public person person01()
{
return new person("12","Czy");
}
}
从源码可知,@Conditional的条件判断类需要实现Conditon接口,条件判断类返回True则@Condtional条件判断成立:
/**
* @author czy
* @create 2021-07-09-16:13
*/
public class Windows implements Condition {
//返回True,则是当前条件满足,即@Conditional条件满足,否则为不满足@Conditional条件
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
System.out.println("当前的环境为"+property);
if(property.contains("Windows"))
return true;
else return true;
}
}
最后的结果,可知当前系统为Windows,成功往容器中注入类:
6.@Import
向Spring容器中注册bean通常有以下几种方式:
①包扫描+给组件标注注解(@Controller、@Servcie、@Repository、@Component),但这种方式比较有局限性,局限于我们自己写的类
②@Bean注解,通常用于导入第三方包中的组件
③@Import注解,快速向Spring容器中导入一个组件
④利用FactoryBean向Spring容器中加入组件
@Import的源码如下:(value可填任意要传入的类)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
从源码可看到,@Import 的使用方式有三种使用方式:
①直接在配置类上标注
打印容器中注册的类
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
//根据Bean的ID获取,
person person=(person) annotationConfigApplicationContext.getBean("person02");
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name: beanDefinitionNames) {
System.out.println("获取的组件为"+name);
}
}
可知注入到容器中的类的ID是类的全路径
②利用实现了ImportSelector接口的类
第一步,编写一个实现了ImportSelector接口的类,String[]中编写需要Improt的类
public class ImportSelectorImplement implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.czy.Entity.Dog","com.czy.Entity.Fish"};
}
}
将下面俩个加进到容器中
输出结果如下:
③利用实现了ImportBeanDefinitionRegistrar接口的类
向容器中注入Snake这个类
public class ImportBeanDefinitionRegistrarCzy implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类
*
* 我们可以通过调用BeanDefinitionRegistry接口中的registerBeanDefinition方法,手动注册所有需要添加到容器中的bean
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(Snake.class);
registry.registerBeanDefinition("Snake", beanDefinition);
}
}
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
//根据Bean的ID获取,
person person=(person) annotationConfigApplicationContext.getBean("person02");
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name: beanDefinitionNames) {
System.out.println("获取的组件为"+name);
}
}
}
输出结果如下:
④使用FactoryBean向Spring容器中注册bean
写一个FactoryBean的实现类,类中的泛型填写要注册的Bean的类
public class FactoryBeanImpl implements FactoryBean<Mouse> {
//返回由FactoryBean创建的bean实例,如果isSingleton()返回true,那么该实例会放到Spring容器中单实例缓存池中
@Override
public Mouse getObject() throws Exception {
System.out.println("正在创建Mouse");
return new Mouse();
}
//返回FactoryBean创建的bean实例的类型
@Override
public Class<?> getObjectType() {
return Mouse.class;
}
//返回由FactoryBean创建的bean实例的作用域是singleton还是prototype
@Override
public boolean isSingleton() {
return false;
}
}
在配置类注册工厂实现类
@Import({Dog.class,ImportSelectorImplement.class,ImportBeanDefinitionRegistrarCzy.class})
@Configuration
public class personConfig {
//根据源码,value值填入的类必须实现Condition接口
@Conditional(value = {Windows.class})
@Bean("person02")
public person person01()
{
return new person("12","Czy");
}
//注入
@Bean
public FactoryBeanImpl FactoryBeanImpl() {
return new FactoryBeanImpl();
}
}
打印Bean:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
//根据Bean的ID获取,
person person=(person) annotationConfigApplicationContext.getBean("person02");
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String name: beanDefinitionNames) {
System.out.println("获取的组件为"+name);
}
// 工厂bean获取的是调用getObject方法创建的对象
Object bean2 = annotationConfigApplicationContext.getBean("FactoryBeanImpl");
Object bean3 = annotationConfigApplicationContext.getBean("FactoryBeanImpl");
System.out.println("获取的工厂bean的类型:" + bean2.getClass());
System.out.println(bean2==bean3);
}
}
获取的组件为personConfig
获取的组件为com.czy.Entity.Dog
获取的组件为com.czy.Entity.Fish
获取的组件为person02
获取的组件为FactoryBeanImpl
获取的组件为Snake
正在创建Mouse
正在创建Mouse
获取的工厂bean的类型:class com.czy.Entity.Mouse
false
可知代码中getbean的填入的是工厂实现类,但是实际获取的是时候会调用getObject方法所创建的对象,即工厂实现类向容器中注册的类。且由于在工厂实现类中填写的isSingleton为false,所以每次获取Bean的时候都会创建一个Bean。
如果向获取工厂实现类,应当以这种写法:
Object bean4 = annotationConfigApplicationContext.getBean("&FactoryBeanImpl");
7.@Value
作用:赋予类的初值。
用法:
①直接赋值 ②数学表示式{#数学表达式}
@Value("#{25-1}")
public Integer age;
@Value("czy")
public String name;
③取配置文件的值(${})需要结合@PropertySource使用
8.@PropertySource
@PropertySource用来给配置类指定配置文件的路径
@PropertySource的源码:
箭头所指为它的value的书写方式,指出配置文件的位置
配置文件:下为配置文件目录和内容
配置类需要指出从哪个配置文件中取值
9.@Autowired
@Autowired:按类型获取Bean ,的作用等价于
applicationContext.getBean(类名.class);
如果找到多个相同类型的组件,那么是将属性名称作为组件的id,到IOC容器中进行查找,这时就相当于是调用了如下这个方法:
applicationContext.getBean(“组件的id”);
@Autowired(required = false):当注入类在容器中找不到时不会报错,会赋值为空
@Autowired可用在:
①属性,用法如上
②方法上,用法:
@Autowired
//在方法上使用@Autowired,会在该类的初始化的时候便调用该方法,从容器中取得该Bean,调用赋值。
public void setBee(Bee bee)
{
this.bee=bee;
}
③构造器上,用法:
在默认情况下会使用无参构造器,可用 @Autowired标注在构造器上,可调用 @Autowired标注的构造器
@Autowired
public person(Bee bee){
this.bee=bee;
}
④放参数上,等同于从容器中获取bean
public person(@Autowired Bee bee){
this.bee=bee;
}
此代码与上面的代码功能一致,都是在初始化的时候进行属性的赋值。
如果只有一个参数,则@Autowired 可省略,直接从容器中拿。
普遍用发:@Bean 然后在参数上使用@Autowired获得参数,默认不写
10.@Qualifier和@Primary
@Qualifier(“组件的id值”)== 寻找指定的id的组件
场景:一个类可能有多个注入bean到容器中,但是bean值不同,可用@Qualifier区分
@Primary(”“组件的id值)== 首先用primary注解注释的组件,需要在Qualifier不启动的状态下使用
11.@Resource和@Inject
@Resource和@Inject是由java提供的,与@Autowired提供的能够基本相同。
@Resource注解中的方法:(name=”“)可以自己指定需要的类,不可与@Qualifier和@Primary(spring框架)等使用,@Inject则可以
二 Bean的生命周期
创建→初始化→销魂
1.在@Bean指定初始化和销毁的方法
在person类中添加方法:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class person {
public String age;
public String name;
public void init()
{
System.out.println("创建person++++++");
}
public void destory()
{
System.out.println("毁坏person+++++++++++"); }
}
在配置类中注入person的时候,在@Bean中添加初始化和销毁的方法
通过打印查看bean的生命周期
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
System.out.println("创建容器完成");
//根据Bean的ID获取,
person person=(person) annotationConfigApplicationContext.getBean("person02");
System.out.println(person);
annotationConfigApplicationContext.close();
}
}
由图可知在容器创建后,便会执行Bean的初始化方法,而在容器关闭的时候,容器也会执行Bean的销毁方法。这种情况是在单实例的情况下
如果设置为多实例:
输出结果如下:
可知bean在多实例情况下,容器不会一开始就执行Bean的创建方法,只有在getBean的时候才会创建Bean,进而执行Bean的Init方法,且在容器关闭的时候也不会执行Bean的销毁方法。
总结:
单实例:在容器启动的时候创建对象,容器关闭的时候销毁对象
多实例:在获取Bean的时候创建对象,容器关闭的时候不会销毁对象
2.让Bean实现spring提供的InitializingBean接口和DisposableBean接口
InitializingBean接口和DisposableBean接口是spring为了管理Bean所设计的接口
InitializingBean:在初始化的时候执行里面的方法
DisposableBean:在销毁的时候执行里面的方法
创建一个Bear类,实现这两个接口即可实现初始化和销毁的功能。
public class Bear implements InitializingBean, DisposableBean {
public Bear() {
System.out.println("Bear constructor...");
}
//销毁Bean执行的方法
@Override
public void destroy() throws Exception {
System.out.println("Bear destroy...");
}
//创建Bean执行的方法(在初始化构造器之后)
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bear afterPropertiesSet...");
}
}
3.让Bean实现JDK提供的@PostConstruct注解和@PreDestroy注解
被@PostConstruct注解修饰的方法通常在构造函数之后,init()方法之前执行。
Constructor(构造方法)→@Autowired(依赖注入)→@PostConstruct(注释的方法)
被@PreDestroy注解修饰的类销毁执行的流程:调用destroy()方法:@PreDestroy→destroy()方法→bean销毁
@PostConstruct源码如下:
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
@PreDestroy 源码如下:
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
可知两个注解都是作用在方法上的。具体使用:
public class Bee {
@PostConstruct
public void init()
{
System.out.println("创建++++++");
}
@PreDestroy
public void destory()
{
System.out.println("毁坏+++++++++++"); }
}
4.让Bean实现BeanPostProcessor 接口
源码如下:
其中有两个方法,postProcessBeforeInitialization用于Bean初始化之前做的一些工作
流程:构造函数→postProcessBeforeInitialization→InitializingBean方法→postProcessAfterInitialization
postProcessAfterInitialization用于Bean初始化之后做的一些工作
代码:
配置类:
@Configuration
@ComponentScan(value="com.czy.Entity")
public class personConfig {
}
@Component
public class Snake {
public Snake()
{
System.out.println("snake");
}
}
自定义的BeanPostProcessor 实现类
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("自定义的postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("自定义的postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
}
输出结果:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(personConfig.class);
System.out.println("创建容器完成");
//根据Bean的ID获取,
Object Object=annotationConfigApplicationContext.getBean("snake");
System.out.println(Object);
annotationConfigApplicationContext.close();
}
}
可知执行的顺序是:先初始化构造器→执行postProcessBeforeInitialization方法→执行postProcessAfterInitialization方法
可以看出getBean填入的应当是类的小写。
三 获取spring中的组件
自定义的组件要想使用Spring容器底层的一些组件,比如ApplicationContext(IOC容器)、底层的BeanFactory等等,那么只需要让自定义组件实现XxxAware接口即可。此时,Spring在创建对象的时候,会调用XxxAware接口中定义的方法注入相关的组件。把spring底层的bean注入到自定义bean中。
以下是实现了Aware接口的类:
实现原理:根据前面所学,ApplicationContextAwareProcessor在ApplicationContext初始化后注入到容器前先执行,它会先检查容器中有无实现ApplicationContextAware的自定义类,然后给这些自定义类返回容器中的ApplicationContext(单例设计)。