spring组件及Bean的生命周期

193 阅读8分钟

注册Bean

xml方式绑定bean

新建一个base.xml

<bean id="person" class="com.enjoy.cap1.Person">
		<property name="name" value="james"></property>
		<property name="age" value="19"></property>
	</bean>

新建一个实体类

    private String name;
    private Integer age;

    public Person() {
        super();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

新建一个MainTest1

public class MainTest1 {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("base.xml");
        Person person = (Person) app.getBean("person");
        System.out.println(person);
    }
}

显然我们现在不使用xml的方式,我们使用注解的方式

注解绑定bean

新建config类

@Configuration
public class MainConfig {

    @Bean
    public Person person() {
        return new Person("sam", "20");
    }

}

新建MainTest2

public class MainTest2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);

        Person person = (Person) app.getBean("person");

        System.out.println(person);

        String[] beanNamesForType = app.getBeanNamesForType(Person.class);
        for (String name : beanNamesForType) {
            System.out.println(name);
        }
    }
}

ComponentScan扫描规则

新建一个MainConfig

@Configuration
@ComponentScan(value = "com.enjoy.cap2", includeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {SamTypeFilter.class})
}, useDefaultFilters = false)
public class MainConfig {

    @Bean
    public Person person() {
        return new Person("sam", "20");
    }

}

@ComponentScan value:指定要扫描的包

excludeFilters = Filter[] 指定扫描的时候按照什么规则排除那些组件

includeFilters = Filter[] 指定扫描的时候只需要包含哪些组件

useDefaultFilters = false 默认是true,扫描所有组件,要改成false

----扫描规则如下

FilterType.ANNOTATION:按照注解

FilterType.ASSIGNABLE_TYPE:按照给定的类型;比如按BookService类型

FilterType.ASPECTJ:使用ASPECTJ表达式

FilterType.REGEX:使用正则指定

FilterType.CUSTOM:使用自定义规则,自已写类,实现TypeFilter接口

自己实现过滤规则

public class SamTypeFilter implements TypeFilter {

    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {

        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        String className = annotationMetadata.getClassName();
        Resource resource = metadataReader.getResource();
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        System.out.println("---------->" + className);
        if (className.contains("er")) {
            return true;
        }

        return false;
    }
}

编写一个测试类

public class Test {
    @Test
    public  void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);



        String[] beanNamesForType = app.getBeanDefinitionNames();
        for(String name:beanNamesForType){
            System.out.println(name);
        }
    }
}

Scope扫描规则

新建一个Config

@Configuration
public class MainConfig {

    @Scope("prototype")
    @Bean
    public Person person() {
        return new Person("sam", "20");
    }
}
  • prototype:多实例: IOC容器启动的时候,IOC容器启动并不会去调用方法创建对象, 而是每次获取的时候才会调用方法创建对象
  • singleton:单实例(默认):IOC容器启动的时候会调用方法创建对象并放到IOC容器中,以后每次获取的就是直接从容器中拿(大Map.get)的同一个bean
  • request: 主要针对web应用, 递交一次请求创建一个实例
  • session:同一个session创建一个实例

编写一个测试类

public class Test {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);


        String[] beanNamesForType = app.getBeanDefinitionNames();
        for (String name : beanNamesForType) {
            System.out.println(name);
        }

        Person bean1 = (Person) app.getBean("person");
        Person bean2 = (Person) app.getBean("person");

        System.out.println(bean1 == bean2);
    }
}

懒加载

新建Config

@Configuration
public class MainConfig {

    @Lazy
    @Bean
    public Person person() {
        System.out.println("开始加载Person--------------");
        return new Person("sam", "20");
    }
}

懒加载: 主要针对单实例bean:默认在容器启动的时候创建对象 懒加载:容器启动时候不创建对象, 仅当第一次使用(获取)bean的时候才创建被初始化

编写测试类

public class Test {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("容器加载完成--------------");

        app.getBean("person");

    }
}

Condition

条件注册bean通过实现Condition接口来进行雕件判断是否注册Bean

public class MacCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();

        Environment environment = conditionContext.getEnvironment();
        String os = environment.getProperty("os.name");
        System.out.println(os);
        if (os.contains("Mac")) {
            return true;
        }
        return false;
    }
}
public class WinCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();

        Environment environment = conditionContext.getEnvironment();
        String os = environment.getProperty("os.name");
        System.out.println(os);
        if (os.contains("Windows")) {
            return true;
        }
        return false;
    }
}
@Configuration
public class MainConfig {

    @Bean
    public Person person() {
        System.out.println("开始加载Person--------------");
        return new Person("person", "200");
    }

    @Conditional(MacCondition.class)
    @Bean
    public Person sam() {
        System.out.println("开始加载Sam--------------");
        return new Person("sam", "20");
    }

    @Bean
    @Conditional(WinCondition.class)
    public Person max() {
        System.out.println("开始加载Max--------------");
        return new Person("max", "21");
    }
}

Import

常见的注册bean的方式有以下

  • 1,@Bean: [导入第三方的类或包的组件],比如Person为第三方的类, 需要在我们的IOC容器中使用
  • 2,包扫描+组件的标注注解(@ComponentScan: @Controller, @Service @Reponsitory @ Componet),一般是针对 我们自己写的类,使用这个
  • 3,@Import:[快速给容器导入一个组件] 注意:@Bean有点简单
    •  a,@Import(要导入到容器中的组件):容器会自动注册这个组件,bean 的 id为全类名
      
    •  b,ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
      
    •  c,ImportBeanDefinitionRegistrar:可以手动添加组件到IOC容器, 所有Bean的注册可以使用BeanDifinitionRegistry
      
  •      写JamesImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口即可
    
  • 4,使用Spring提供的FactoryBean(工厂bean)进行注册
@Configuration
@Import(value = {Dog.class, Cat.class, SamImportBeanSelector.class, SamImportBeanDefinitionRegistrar.class})
public class MainConfig {

    @Bean
    public Person person() {
        System.out.println("开始加载Person--------------");
        return new Person("person", "200");
    }

    @Bean
    public SamFactoryBean samFactoryBean() {
        return new SamFactoryBean();
    }

}
public class SamFactoryBean implements FactoryBean<Monkey> {
    public Monkey getObject() throws Exception {
        return new Monkey();
    }

    public Class<?> getObjectType() {
        return Monkey.class;
    }

    public boolean isSingleton() {
        return true;
    }
}
public class SamImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        boolean b = beanDefinitionRegistry.containsBeanDefinition("com.enjoy.cap6.bean.Tiger");
        boolean b2 = beanDefinitionRegistry.containsBeanDefinition("com.enjoy.cap6.bean.Fish");

        if (b && b2) {
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Pig.class);
            beanDefinitionRegistry.registerBeanDefinition("pig", rootBeanDefinition);
        }
    }
}
public class SamImportBeanSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.enjoy.cap6.bean.Tiger", "com.enjoy.cap6.bean.Fish"};
    }
}
public class Test {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
        System.out.println("容器加载完成--------------");

        Object samFactoryBean = app.getBean("samFactoryBean");
        Object samFactoryBean2 = app.getBean("samFactoryBean");

        System.out.println("bean的类型为:" + samFactoryBean.getClass());

        System.out.println(samFactoryBean == samFactoryBean2);

        System.out.println(app.getBean("&samFactoryBean"));

        String[] beanNamesForType = app.getBeanDefinitionNames();
        for (String name : beanNamesForType) {
            System.out.println(name);
        }

    }
}

bean的生命周期

bean的生命周期是指 bean创建-初始化-销毁 的过程

bean的生命周期是由容器进行管理的,我们可以自定义bean的初始化和销毁的,在容器在bean 进行到当前生命周期时来调用自定义的初始化和销毁方法,一般有以下四种方法

指定初始化和销毁方法

之前在base.xml中指定init-method和destroy-method,但是现在可以用注解

public class Bike {
    public Bike() {
        System.out.println("Bike constructor..............");
    }

    public void init() {
        System.out.println("Bike .....init.....");
    }

    public void destory() {
        System.out.println("Bike.....destory");
    }
}

在配置类里面通过@Bean(inintMethod="",destroyMethon="")

@Bean(initMethod = "init", destroyMethod = "destory")
public Bike bike() {
    return new Bike();    
}
  • 单实例:当容器关闭的时候会自动调用destroy方法

    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap7MainConfigOfLifeCycle.class);
    
        System.out.println("IOC容器创建完成........");
        app.close();
    
    
    }
    
  • 多实例:容器值负责初始化,但不回管理bean,容器关闭不回调用销毁方法

实现InitializingBean和DisposableBean接口

通过实现以上两个接口啦模拟bean的初始化和销毁

  • InitializingBean:afterPropertiesSet()方法,当beanfactory吧bean对象创建好,且吧bean的属性设置好了的时候,回调用这个方法相当于初始化方法
  • DisposableBean:destroy()方法,当bean销毁时,会把单例bean进行销毁
@Component
public class Train implements InitializingBean, DisposableBean {

    public Train() {
        System.out.println("Train__________________constructor");
    }

    public void destroy() throws Exception {
        System.out.println("Train___________________destory");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("Train____________________init");
    }
}
@ComponentScan("com.enjoy.cap7.bean")
@Configuration
public class MainConfig {
	//……
}
@Test
public void test() {
    AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap7MainConfigOfLifeCycle.class);

    System.out.println("IOC容器创建完成........");
    app.close();


}

JSR250的@PostConstrct和@PreDretroy

  • @PostConstruct在Bean创建完成且赋值完成后进行初始化,属于JDK规范注解

  • @PreDestroy 在Bean被移除之前进行通知,在容器销毁前进行亲历工作

@Component
public class Jeep {
    public Jeep() {
        System.out.println("Jeep.....constructor........");
    }

    @PostConstruct
    public void init() {
        System.out.println("Jeep.....@PostConstruct........");
    }

    @PreDestroy
    public void destory() {
        System.out.println("Jeep.....@PreDestroy......");
    }
}
@ComponentScan("com.enjoy.cap7.bean")
@Configuration
public class MainConfig {
	……
}
@Test
public void test() {
    AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap7MainConfigOfLifeCycle.class);

    System.out.println("IOC容器创建完成........");
    app.close();


}

BeanPostProcessor

BeanPostProcessor:bean的后置处理器,在bean初始化之前调用拦截,主要用于bean初始化之后进行一些处理工作:

  • postProcessorBeforeInitialization(),在备bean初始化之前进行后置处理工作(在init-method之前)
  • postProcessorAfterInitialization(),在bean初始化之后后置处理工作,例如(InitializingBean的afterPropertiesSet())
@Component
public class SameBeanPorcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("postProcessBeforeInitialization______" + beanName + "____" + beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization_______" + beanName + "____" + beanName);
        return bean;
    }
}
@ComponentScan("com.enjoy.cap7.bean")
@Configuration
public class MainConfig {
	……
}
@Test
public void test01() {
    AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap7MainConfigOfLifeCycle.class);

    System.out.println("IOC容器创建完成........");
    app.close();


}

bean的生命周期时可控的

容器启动及BeanPostProcessor

beanPortProcessor原理:

AnnotationConfigApplicationContext()
->refresh()
-->finishBeanFactoryInitialization()
--->preInstantiateSingletons()
---->getBean()
----->doGetBean()
------>createBean()
------->doCreateBean()
--------->{
					createBeanInstance(),
					populateBean(),
					initializeBean()
----------->{
						applyBeanPostProcessorsBeforeInitialization(),
						invokeInitMethods(),
 						applyBeanPostProcessorsAfterInitialization()
						}
					}

Spring底层对BeanPostPorcessor使用

Spring底层对BeanPostProcessor的使用, 包括bean的赋值, 注入其它组件, 生命周期注解功能,@Async, 等等

截屏2020-05-13 下午12.09.07

ApplicationContextAwareProcessor

此类帮助我们创建IOC容器,跟进ApplocationContextAwareProcessor我们发现,这个后置处理器就是判断我们的 bean是否实现了我们的ApplicationContextAware接口,并处理相应的逻辑,其实所有的后置处理器原理均是如此

@Component
public class Train implements InitializingBean, DisposableBean {

    public Train() {
        System.out.println("Train......constructor............");
    }

    //当我们bean销毁时,调用此方法
    @Override
    public void destroy() throws Exception {
        System.out.println("Train......destory......");
        //logger.error
    }

    //当我们的bean属性赋值和初始化完成时调用
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Train.......afterPropertiesSet()...");

    }

}

我们分析一下ApplicationContextAwareProcessor里面的方法

@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
   AccessControlContext acc = null;

   if (System.getSecurityManager() != null &&
         (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
               bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
               bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
      acc = this.applicationContext.getBeanFactory().getAccessControlContext();
   }

   if (acc != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareInterfaces(bean);
         return null;
      }, acc);
   }
   else {
      invokeAwareInterfaces(bean);
   }

   return bean;
}
  • 在创建plane对象,还没有初始化之前,先判断是不是实现了ApplicationContextAware接口,如果是的话就调用invokeAwareInterfaces();并且吧bean注入

  • 进入invokeAwareInterfaces(),判断是哪个类型的Aware如果是ApplicationContextAware, 就将当前的bean转成ApplicationContextAware类型, 调用setApplicationContext(), 把IOC容器注入到Plane里去;

    private void invokeAwareInterfaces(Object bean) {
       if (bean instanceof Aware) {
          if (bean instanceof EnvironmentAware) {
             ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
          }
          if (bean instanceof EmbeddedValueResolverAware) {
             ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
          }
          if (bean instanceof ResourceLoaderAware) {
             ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
          }
          if (bean instanceof ApplicationEventPublisherAware) {
             ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
          }
          if (bean instanceof MessageSourceAware) {
             ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
          }
          if (bean instanceof ApplicationContextAware) {
             ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
          }
       }
    }
    

BeanValidationPostProcessor分析

在对象创建完,给bean赋值之后,在web用的特别多,把页面提交的值进行校验

//初始化之前校验
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   if (!this.afterInitialization) {
      doValidate(bean);
   }
   return bean;
}
//初始化之后校验
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   if (this.afterInitialization) {
      doValidate(bean);
   }
   return bean;
}

InitDestroyAnnotationBeanPostProcessor

用于处理@PostConstruct和@PreDestroy

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
   try {
      metadata.invokeInitMethods(bean, beanName);
   }
   catch (InvocationTargetException ex) {
      throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
   }
   return bean;
}
public void invokeInitMethods(Object target, String beanName) throws Throwable {
   Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
   Collection<LifecycleElement> initMethodsToIterate =
         (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
   if (!initMethodsToIterate.isEmpty()) {
      boolean debug = logger.isDebugEnabled();
      for (LifecycleElement element : initMethodsToIterate) {
         if (debug) {
            logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod());
         }
         element.invoke(target);
      }
   }
}

@Value赋值

public class Bird {


    @Value("sam")
    private String name;

    @Value("#{20-1}")
    private Integer age;

    @Value("${bird.color}")
    private String color;


    @Override
    public String toString() {
        return "Bird{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }

    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 getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

@Configuration
@PropertySource(value = "classpath:/test.properties")
public class MainConfig {

    @Bean
    public Bird bird() {
        return new Bird();
    }
}
public class Cap8Test {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);


        System.out.println("容器加载完成--------------");

        Bird bird = (Bird) app.getBean("bird");
        System.out.println(bird);

        String[] beanDefinitionNames = app.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }


        ConfigurableEnvironment environment = app.getEnvironment();
        System.out.println(environment.getProperty("bird.color"));

        app.close();


    }
}

自动装配

自动装配:sping利用依赖注入(DI)完成对IOC容器中的各个组件的依赖关系赋值

代码如下:

@Controller
public class TestController {
    @Autowired
    private TestService testService;
}
@Service
public class TestService {

    @Autowired
    private TestDao testDao;

    public void printIn() {
        System.out.println("Service...dao...." + testDao);
    }
}

@Repository
public class TestDao {
    private String flag = "1";

    public String getFlag() {
        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }

    @Override
    public String toString() {
        return "TestDao...... [flag=" + flag + "]";
    }

}
@Configuration
@ComponentScan({"com.enjoy.cap9.controller", "com.enjoy.cap9.service", "com.enjoy.cap9.dao", "com.enjoy.cap9.bean"})
public class MainConfig {
  //……
}

public class Cap9Test {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext app = new 
          AnnotationConfigApplicationContext(MainConfig.class);

        System.out.println("容器加载完成--------------");

        TestService bean = app.getBean(TestService.class);
        bean.printIn();
        TestDao bean1 = app.getBean(TestDao.class);
        System.out.println(bean1);


    }
}

@Autowired表示默认优先按类型去容器中找对应的组件,相当于app.getBean(TestDao.class)去容器获取id为testDao的bean, 并注入到TestService的bean中;

注意事项

  • Spring

    • 如果容器中有多个testDao要加载哪一个呢?

    可以使用@Autowired和@Qualifier来指定使用哪个bean

    • 如果容器中没有testDao呢?

    会报错,因为@Autowired里面的属性required默认为true就是必须要找到加载的bean

    • @Primary指定的bean是如何加载的呢

    • @Primary是针对指所有testDao bean的默认值,除非@Qualifier指定了加载哪个,意思就是@Qualifier指定的bean不回被@Priamry修改

  • JSR250

    • @Resource
      • 不能支持@Primary
      • 不能支持@Autowired(required=false)的情况
  • JSR330

    • @Inject
      • 支持@Parimary
      • 不能支持@Autowired(required=false)的情况
      • 非Spring框架支持,需要映入javax.inject 依赖

@Autowaired可以在构造函数,构造函数参数中使用

@Component
public class Sun {

    private Moon moon;

    @Autowired
    public Sun(Moon moon) {
    //public Sun(@Autowaired Moon moon) {
        this.moon = moon;
    }

    public Moon getMoon() {
        return moon;
    }


    public void setMoon(Moon moon) {
        this.moon = moon;
    }

    @Override
    public String toString() {
        return "Sun [moon=" + moon + "]";
    }
}

Aware注入spring底层组件原理

如果我们组件想要使用Spring底层的组件(ApplicationContext,beanFactory),可以实现xxxAware接口,回调用接口规定的方法注入到相关组件

我们找到Aware接口,可以查看这个接口的实现类

Aware (org.springframework.beans.factory)
ApplicationEventPublisherAware (org.springframework.context) //注入事件派发器
NotificationPublisherAware (org.springframework.jmx.export.notification)
MessageSourceAware (org.springframework.context)//资源国际化
EnvironmentAware (org.springframework.context)//运行环境
BeanFactoryAware (org.springframework.beans.factory)
ResourceLoaderAware (org.springframework.context)//资源加载器
EmbeddedValueResolverAware (org.springframework.context)
ImportAware (org.springframework.context.annotation)
LoadTimeWeaverAware (org.springframework.context.weaving)
BeanClassLoaderAware (org.springframework.beans.factory)//类加载器
BeanNameAware (org.springframework.beans.factory)//bean名称
ApplicationContextAware (org.springframework.context)

可以通过实现以上的aware来获取相关的组件

@Component
public class Light implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {

    private ApplicationContext applicationContext;

    public void setBeanName(String s) {
        System.out.println("当前bean的name为" + s);
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("传入的IOC容器: " + applicationContext);
        this.applicationContext = applicationContext;
    }

    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        String s = stringValueResolver.resolveStringValue("你好${os.name}, 计算#{3*8}");
        System.out.println("解析的字符串为---" + s);
    }
}

通过以上的方法可以把Spring底层的组件组入到自定义bean中,ApplicationContextAware是通过ApplicationContextAwareProcessor来处理的,其他的也一样,XXXAware也是有相关的Processor来处理,也就是后置处理器来处理的。