1.环境说明:
jdk version : jdk1.6
Spring version : 4.1.9.RELEASE
tomcat version : 7.0.57
使用到的相关技术:Shiro , SpringMvc , Spring , Mybatis
2.bugs:
bug 1:
①因为业务需要,要在Controller这一层加入公用逻辑。决定使用 AOP (这里使用的是 Spring-AOP)技术实现。使用注解开发,在定义的切面类上加上注解
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.aspectj.lang.annotation.Around;
@Component
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Aspect{
//..........
@Around("execution(* com.xxx.web.*.form(..))")
public Object doSomething(ProceedingJoinPoint pjp){
// do something
}
}
bug现象:切面内的代码没有被执行,再次测试发现 Aspect 没有被初始化。然后上网查找相关资料,有大部分人说"Controller 层的 aspect 只能再spring-mvc.xml"中进行配置。然后在 spring-mvc.xml 中添加了如下配置:
<bean id="aspect" class="com.xxx.aspect.Aspect"/>
<aop:config proxyTargetClass = true>
<aop:aspect id="xxxAspect" ref="aspect">
<aop:pointcut id="form" expression="execution(* com.xxx.web.*.form(..))"/>
<aop:around method="doSomething" pointcut-ref="form"/>
</aop:aspect>
</aop:config>
再次测试,成功执行了 Aspect 中的代码。但是,这是不对的,用注解的方式在Controller层实现AOP是完全没有问题的。网上包括某些书上说"AOP注解的方式需要在配置文件中加入配置":
<aop:aspectj-autoproxy />
经过我测试发现,没有这个配置也完全不会影响注解方式的AOP实现。但是我第一次就是使用注解却没有成功是为什么呢?原因在这里:
<!-- 使用Annotation自动注册Bean,只扫描@Controller -->
<context:component-scan base-package="com.xxx" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
SpringMvc 的 ApplicationContext 和 Spring 的 ApplicationContext 不是同一个,所以这里为了避免同一个类被初始化两次的问题,加了组件扫描的条件,只初始化内些有@Controller注解的类。所以我在这里加入另一个扫描条件,使得我定义的Aspect可以被SpringMvc初始化:
<!-- 使用Annotation自动注册Bean,只扫描@Controller -->
<context:component-scan base-package="com.xxx" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
这样就成功的代理了Controller。