Maven
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
一般都在spring 框架中使用,即
org.springframework.web 之类的依赖最好也存在
如果为 一般的spring 环境,且存在 applicationContext.xml
存在的情况下需要开启该xml 中的配置如下:
或
<aop:aspectj-autoproxy proxy-target-class="true" />
<aop:config expose-proxy="true">
<aop:pointcut id="allManagerMethod" expression="(execution(* com.test.demo.service..*.*(..))
or execution(* com.test.demo.test.manager..*.*(..)))
and not execution(* com.test.demo.ignore.service*(..)) and not execution(* com.test.demo.ignore.test.*(..))
"/>
<aop:advisor advice-ref="tAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
<!-- 单数据源事务 -->
<tx:advice id="tAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="start*" propagation="REQUIRED" rollback-for="com.test.demo.TestException"/>
<tx:method name="execute*" propagation="REQUIRED" rollback-for="com.test.demo.TestException"/>
........
</tx:attributes>
</tx:advice>
实际在类中定义的使用案例(一般方法和携带自定义注解的方法增强)
@Aspect
@Component
public class MyAspect {
// 可以注入一般的Service
// @Resource(name = "userService")
// private UserService userService;
// 包路径下的所有
@Pointcut("execution(* com.test.demo.test..*(..))")
public void testPackage() {
// 定义切入点
}
// 某一路径下的类的 某一方法,这里 Taskhandler 为某一接口 taskCreate为指定的方法
@Pointcut("execution(* com.test.demo.Taskhandler+.taskCreate (..))")
public void taskCreate() {
// 定义切入点
}
// 某一个注解
@Pointcut("@annotation(com.test.demo.test.MyAnnotation)")
public void MyAnnotation() {
// 定义切入点
}
// 循环增强 前后都增强 value 即上方定义的Pointcut
@Around(value = "MyAnnotation()")
public Object annotationTest(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
// 获取请求中携带的参数
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String idStr = request.getParameter("id").toString();
String name = request.getParameter("name").toString();
// 或 request.getAttribute("") 获取参数
// .................... 自己的其他操作
// 执行完成后放行 正常进入原有方法
return joinPoint.proceed(args);
}
// 前增强 在进入指定方法前执行的代码
@Before(value = "testPackage()")
public void testMethod1() {
// ....... 其他任何操作 这里可以与 ThreadLocal 连用 在ThreadLocal 中存储或者获取,
// 或者修改一些数据 去做部分处理 但不要忘记 threadLocal 的 remove
}
// 后增强 在指定方法结束后执行代码 使用 || 可以标识多个 pointCut 都要执行
@After(value = "taskCreate() || testPackage() || MyAnnotation()")
public void testMethod1() {
// ....... 其他任何操作 这里可以与 ThreadLocal 连用 在ThreadLocal 中存储或者获取,
// 或者修改一些数据 去做部分处理 但不要忘记 threadLocal 的 remove
}
}
从 joinPoint 获取当前方法对象 Method
入参类型 ProceedingJoinPoint joinPoint
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
// 获取到 方法上的注解对象后,如果给注解定义了一些属性,那么此时也可以通过该注解的对象获取到
其他注解
@AfterReturning
在方法执行完成后的增强部分
@AfterThrowing
在异常抛出后的增强部分