欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring中ApplicationContextAware接口的用法

程序员文章站 2022-03-03 13:16:18
...

1. 这个接口有什么用?

加载Spring配置文件时,如果Spring配置文件中所定义或者注解自动注入的Bean类实现了ApplicationContextAware 接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware 接口中的方法:


public void setApplicationContext(ApplicationContext context) throws BeansException


2. 可以用它来干什么?

获得了ApplicationContext对象之后,就可以获取容器中的bean,问题是我在需要bean的地方自动注入不是一样可以获得这个bean吗?这么做ms多此一举哦?其实还有一个场景,当你需要使用静态方法的时候,但是这些静态方法又依赖了一些注入的bean,看到这里就了解了吧,好了,上一个实例,看如何把bean放到静态方法中使用

@Component
public class AppContextUtil implements ApplicationContextAware {
    private static ApplicationContext appContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.appContext = applicationContext;
    }

    private static Object getBean(String beanName, Class clazz){
        return appContext.getBean(beanName);
    }

    /**如果bean类中有方法做为切面的切入点(pointcut),那么getbean类型必须是接口,以接口的方式生成代理类,
     * 否则会报错代理类无法转换成目标类型
     * @return
     */
    private static Action getDog(){
        Action dog = (Action)appContext.getBean("dog", Action.class);
        return dog;
    }

    /**如果bean的类是基于接口实现的,只要其中的方法没有做为切面的切入点,那么getbean的类型可以是实现类,也可以是接口
     * @return
     */
    private static Panda getPanda(){
        return (Panda)appContext.getBean("panda", Panda.class);
    }

    public static void pandaDance(){
        getPanda().dance();
    }

    public static void DogSay(){
        Action dog = getDog();
        dog.say();
    }

}


@Component("dog")
public class Dog implements Action {

    @Override
    public void say() {
        System.out.println("dog bark!");
    }

    @Override
    public void run() {
        try {
            System.out.println("dog run!");
            Thread.currentThread().sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Component("panda")
public class Panda implements Animal{
    @Override
    public void dance(){
        System.out.println("panda dancing!");
    }
}

如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware 接口,那么在加载Spring配置文件时,会自动调用ApplicationContextAware 接口中的
public void setApplicationContext(ApplicationContext context) throws BeansException


在AppContextUtil类中定义一个类型为ApplicationContext的静态变量appContext,当Spring自动注入AppContextUtil的bean时,就会自动调用其setApplicationContext方法,把应用的context当做参数传进去,然后我们把它赋值给静态的appContext,这样在其他的静态方法中就可以通过appContext的getBean方法获取对应的bean,然后进行操作。


如上例所示:
private static Action getDog()
为什么返回类型是一个接口,而不是Dog类本身,因为在示例中,我做了一个切面类,把Dog类里的say()方法当做切入点,此时getBean必须指定接口类型,jdk默认以接口的方式实现代理类,否则会报错代理类不能转换成目标类型。


private static Panda getPanda()
这个静态方法返回的是Panda类(虽然它也实现了一个接口Animal),Panda类中没有方法被做为切入点,所以可以直接用目标类型,当然这里也可以用接口类型Animal