Spring MVC中AOP无效、不起作用(配置问题)

最近做的一个项目需要由原来的单个数据改为多数据源方案,固想到了使用spring aop方式简化各模块使用数据源的切换功能,但论如何配置aop的bean都无法生效,无法切换数据源
我的的配置
1.引入aop所需的jar包( aopalliance-1.7.4.jar,aspectjweaver-1.7.4.jar
2. 配置容器初始化时需要的XML文件
beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd">



3.设置AOP自动代理
<!-- AOP自动代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
4.配置AOP
	<!-- 横切关注点 -->
	<beans:bean id="dataSourceAspect" class="com.idra.common.utils.db.DataSourceAspect"></beans:bean>
	
	<!-- 配置AOP拦截规则 expression 正则-->
	<aop:config proxy-target-class="true">
	    <aop:aspect id="bAspect" ref="dataSourceAspect">
	        <aop:pointcut id="bPointcut" expression="execution(* com.idra.*.serviceimpl.*.*(..))" />
	        <aop:before pointcut-ref="bPointcut" method="changeDateSource" />
	    </aop:aspect>
	    <aop:aspect id="aAspect" ref="dataSourceAspect">
	        <aop:pointcut id="aPointcut" expression="execution(* com.idra.*.serviceimpl.*.*(..))" />
	        <aop:after pointcut-ref="aPointcut" method="clearDataSource" />
	    </aop:aspect>
	</aop:config>


5.切换数据源的横切类, 定义AOP切面以便拦截所有带有注解@DataSource的类或方法,取出注解的值作为数据源标识放到DynamicDataSourceHolder的线程变量中:
public class DataSourceAspect {
	private static Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
	
	public DataSourceAspect(){
		logger.info("数据源切换类");
	}
	
    /**
     * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
     * 
     * @param point
     * @throws Exception
     */
    //@Before("@annotation(com.idra.common.utils.db.DataSource)") //前置通知
    //@Before("execution(* com.idra.*.serviceimpl.*.*(..))") //前置通知
    public void changeDateSource(JoinPoint point) throws Exception {
    	logger.info("改变数据源");
        Class<?> target = point.getTarget().getClass();
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 默认使用目标类型的注解,如果没有则使用其实现接口的注解
        for (Class<?> clazz : target.getInterfaces()) {
            resolveDataSource(clazz, signature.getMethod());
        }
        resolveDataSource(target, signature.getMethod());
    }
    private void resolveDataSource(Class<?> clazz, Method method) {
        try {
            Class<?>[] types = method.getParameterTypes();
            // 默认使用类型注解
            if (clazz.isAnnotationPresent(DataSource.class)) {
                DataSource source = clazz.getAnnotation(DataSource.class);
                logger.info("使用数据源:" + source);
                DataSourceContextHolder.setDataSource(source.value());
            }
            // 方法注解可以覆盖类型注解
            Method m = clazz.getMethod(method.getName(), types);
            if (m != null && m.isAnnotationPresent(DataSource.class)) {
                DataSource source = m.getAnnotation(DataSource.class);
                logger.info("使用数据源:" + source);
                DataSourceContextHolder.setDataSource(source.value());
            }
        } catch (Exception e) {
        	logger.info(clazz + ":" + e.getMessage());
        }
    }
}


6.在service层添加 注解切换数据源 @DataSource(value="dataSource2")
@Service("idraCommonService")
@DataSource(value="dataSource2")
public class CommonServiceImpl extends SqlSessionDaoSupport implements CommonService{
……
}

满怀惊喜的运行程序,启动测试,确无法按预定想法完美切换数据,失落……,经多次检查,甚至是将配置方式改为注解方式扔没有解决问题,也没有发现什么异常,但aop切面就是不执行,经多方查找后在

找到了解决方案,原来是我把aop配错位置了,文中说的好我们是在springMVC上aop检测那么所有扫描检测都应该在spirng-mvc的配置文件中完成,而不是放在spring( applicationContext)的配置中,既然找到了解决办法就立即行动,将aop相关配置挪到spirng-mvc.xml中,启动测试,完美实现切换。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值