Spring ApplicationContextAware应用

前言

Spring给用户提供了很多干预bean的外部接口,最近就看到了一个比较有趣的接口的ApplicationContextAware。既然说到应用,就要假设一个场景:UserA登陆,要走ServiceA。UserB登陆,要走ServiceB。不同的角色给不同的逻辑处理,比如区分白金用户,一般用户等等。本篇就简单说一下在Spring框架下的实现思路。更多Spring内容进入【Spring解读系列目录】

ApplicationContextAware

public interface ApplicationContextAware extends Aware {
	/**
	 * Set the ApplicationContext that this object runs in.
	 * Normally this call will be used to initialize the object.
	 * <p>Invoked after population of normal bean properties but before an init callback such
	 * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
	 * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
	 * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
	 * {@link MessageSourceAware}, if applicable.
	 * @param applicationContext the ApplicationContext object to be used by this object
	 * @throws ApplicationContextException in case of context initialization errors
	 * @throws BeansException if thrown by application context methods
	 * @see org.springframework.beans.factory.BeanInitializationException
	 */
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

上面的代码来自Spring源码。首先先介绍一下这个接口里的唯一方法setApplicationContext()。从官方描述来看Set the ApplicationContext that this object runs in.是说,这个方法可以在本对象运行时设置ApplicationContext。什么意思呢,就是能够拿到运行时的ApplicationContext,然后根据内容进行设置。直接说肯定比较抽象,下面通过一个例子展示一下它的功能。

Sample

首先假设有一个接口OrderDao,还有两个类去实现不同的逻辑OrderDaoImplAOrderDaoImplB,还有一个OrderServiceImpl用来去区分要使用哪一个Dao去实现具体的逻辑。最终希望,UserA登陆执行OrderDaoImplAUserB登陆执行OrderDaoImplB

public interface OrderDao {
    public void logical(String user);
}
@Component
public class OrderDaoImplA implements OrderDao{
    public void logical(String user){
        System.out.println(user);
    }
}
@Component
public class OrderDaoImplB implements OrderDao{
    public void logical(String user){
        System.out.println(user);
    }
}

重点就在于要如何实施OrderServiceImpl,其实也非常简单。首先要获取到ApplicationContext,因为拿到这个就能够对Spring实例化后的bean进行区分处理,所以ApplicationContextAware用法就在这里。

@Service
public class OrderServiceImpl implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    public void changeOrder(String userName){
    	//对不同的User进行分类处理,并且根据User拿到对应的bean,执行不同的逻辑
        if (userName.equals("UserA")){
            ((OrderDao)applicationContext.getBean("orderDaoImplA")).logical("UserA move");
        }else if (userName.equals("UserB")){
            ((OrderDao)applicationContext.getBean("orderDaoImplB")).logical("UserB move");
        }
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext; //获取到applicationContext
    }
}
public class AOPMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext anno=new AnnotationConfigApplicationContext(AppConfig.class);
        OrderServiceImpl orderService=anno.getBean(OrderServiceImpl.class);
        orderService.changeOrder("UserA");
        //orderService.changeOrder("UserB");
    }
}
输出,传入哪个User,就使用哪个逻辑。
UserA move
//UserB move

另一个思路

上面的例子呢,只是为了展示ApplicationContextAware的使用方法是什么样的,就举出来的例子而言,我们还有一个更加便捷的办法。那就是使用一个Map去交给Spring处理,这个方法对于刚刚假设的场景来说更加的便捷,我们只需要把OrderServiceImpl 改造成下面的样子,同样是可以完成这个效果的。

@Service
public class OrderServiceImpl {
	//Spring会自动把所有符合OrderDao接口的实现给实例化到map中
	// 也就意味着这个map里存的是
	// <(String)orderDaoImplA:(Object)OrderDaoImplA>,
	// <(String)orderDaoImplB:(Object)OrderDaoImplB>
    Map<String,OrderDao> map;
    @Autowired
    public void setMap(Map<String, OrderDao> map) { 
        this.map = map; 
    }
    public void changeOrder(String userName){
    	//因此我们只要在map中拿到对应的处理类就可以了
        if (userName.equals("UserA")){
            map.get("orderDaoImplA").logical("UserA move");
        }else if (userName.equals("UserB")){
            map.get("orderDaoImplB").logical("UserB move");
        }
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ApplicationContextAware接口是Spring框架中的一个扩展点,用于在实例化后,将ApplicationContext对象注入到Bean中。这样,Bean就可以通过ApplicationContext对象来访问Spring容器的各种资源和功能。 下面是一些ApplicationContextAware的应用实例[^1]: 1. 访问Spring容器中的其他Bean:通过ApplicationContext对象,可以获取其他Bean的实例,从而实现Bean之间的协作和调用。 2. 获取应用程序的环境信息:通过ApplicationContext对象,可以获取应用程序的环境信息,如操作系统信息、系统属性等。 3. 获取应用程序的配置信息:通过ApplicationContext对象,可以获取应用程序的配置信息,如数据库连接信息、缓存配置等。 4. 发布应用程序事件:通过ApplicationContext对象,可以发布应用程序的事件,从而实现事件驱动的编程模型。 5. 国际化支持:通过ApplicationContext对象,可以获取MessageSource对象,从而实现国际化支持。 下面是一个使用ApplicationContextAware接口的示例代码: ```java import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class MyBean implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void doSomething() { // 使用ApplicationContext对象进行操作 // ... } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值