Spring ApplicationContextAware应用

本文介绍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");
        }
    }

}
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值