Spring 高级 Aware 接口及 InitializingBean 接口

一、Aware

1、Aware 接口的作用

Aware 接口提供了一种【内置】 的注入手段,例如

  • BeanNameAware 注入 bean 的名字
  • BeanFactoryAware 注入 BeanFactory 容器
  • ApplicationContextAware 注入 ApplicationContext 容器
  • EmbeddedValueResolverAware 注入 ${} 解析器

2、示范

package com.mangoubiubiu.show.a06;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;


/**
 * 在Bean创建过程中,初始化之前,就会回调BeanNameAware  接口 将Bean的名字传过来
 */
@Slf4j
public class MyBean implements BeanNameAware , ApplicationContextAware {
    @Override
    public void setBeanName(String s) {
     log.info("当前bean:{},名字叫{}",this,s);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("当前bean:{},容器是{}",this,applicationContext);
    }
}
package com.mangoubiubiu.show.a06;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.GenericApplicationContext;

@Slf4j
public class A06Application {


    public static void main(String[] args) {

       /*
        Aware 接口提供了一种【内置】 的注入手段,例如
                * BeanNameAware 注入 bean 的名字
                * BeanFactoryAware 注入 BeanFactory 容器
                * ApplicationContextAware 注入 ApplicationContext 容器
                * EmbeddedValueResolverAware 注入 ${} 解析器
        */



        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("myBean",MyBean.class);
        context.refresh();//初始化容器
        context.close();//关闭容器



    }

}

二、InitializingBean

1 InitializingBean 接口的作用

  1. InitializingBean 接口提供了一种【内置】的初始化手段
  2. 对比
    • 内置的注入和初始化不受扩展功能的影响,总会被执行
    • 而扩展功能受某些情况影响可能会失效
    • 因此 Spring 框架内部的类常用内置注入和初始化

2、示范

package com.mangoubiubiu.show.a06;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;


/**
 * 在Bean创建过程中,初始化之前,就会回调BeanNameAware  接口 将Bean的名字传过来
 */
@Slf4j
public class MyBean implements BeanNameAware , ApplicationContextAware, InitializingBean {
    @Override
    public void setBeanName(String s) {
     log.info("当前bean:{},名字叫{}",this,s);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("当前bean:{},容器是{}",this,applicationContext);
    }

    /**
     * 先去回调Bean的Aware 接口 然后再去执行的是InitializingBean的初始化方法
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("当前bean:{},初始化",this);
    }
}

三、面试考点(重点!!!) 

问题一:Aware 接口的以下功能都能用@Autowired就能实现,为啥还要用Aware 接口呢

  • BeanFactoryAware 注入 BeanFactory 容器
  • ApplicationContextAware 注入 ApplicationContext 容器
  • EmbeddedValueResolverAware 注入 ${} 解析器

答:1、@Autiwired的解析需要用到bean后处理器,属于扩展功能。

       2、而Aware 接口属于内置功能,不加任何扩展,Spring就能识别

         某些情况下,扩展功能会失效,而内置功能不会失效

示范

package com.mangoubiubiu.show.a06;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;


/**
 * 在Bean创建过程中,初始化之前,就会回调BeanNameAware  接口 将Bean的名字传过来
 */
@Slf4j
public class MyBean implements BeanNameAware , ApplicationContextAware, InitializingBean {
    @Override
    public void setBeanName(String s) {
     log.info("当前bean:{},名字叫{}",this,s);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("当前bean:{},容器是{}",this,applicationContext);
    }

    /**
     * 先去回调Bean的Aware 接口 然后再去执行的是InitializingBean的初始化方法
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("当前bean:{},初始化",this);
    }

    @Autowired
    public void addAutowired(ApplicationContext applicationContext){
        log.info("使用 @Autowired 注入 当前bean:{},容器是{}",this,applicationContext);
    }

    @PostConstruct
    public void init(){
        log.info("使用 @PostConstruct 当前bean:{},初始化",this);

    }
}

 

 

 

posted @ 2022-08-28 14:30  KwFruit  阅读(93)  评论(0编辑  收藏  举报