使用注解对Spring动态代理进行开发(@Aspect,@Around,@Pointcut)
进行AOP编程有一下要素:
- 原始类
- 增强方法
- 切入点
- 组装它们
1.准备原始类
UserService接口
public interface UserService {
public void register(User user);
public Boolean login(String name, String password);
}
UserServiceImpl实现类
public class UserServiceImpl implements UserService {
@Override
public void register(User user) {
System.out.println("UserServiceImpl.register");
}
@Override
public Boolean login(String name, String password) {
System.out.println("UserServiceImpl.login "+name+" "+password );
return true;
}
}
2.增强方法
将使用到@Aspect,@Around两个注解
1.先搭架子
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
//@Aspect 指定这个类切面为切面实现
@Aspect
public class MyAspect {
//@Around() 指定为这个方法为增强方法,在括号里添加切入点表达式
@Around()
public Object ServiceAspect(ProceedingJoinPoint joinPoint) throws Throwable {
Object ret=joinPoint.proceed();
return ret;
}
}
可以和之前的JDK方式对比
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret= method.invoke(userService,args);
return ret;
}
也可以和MethodInterceptor方式对比
public Object invoke(MethodInvocation invocation) throws Throwable {
Object ret=invocation.proceed();
return ret;
}
就那么回事儿,所以不过多解释和研究其中的内容
2.填入需要添加的方法和切入点表达式
完整代码如下
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@Around("execution(* *(..))")
public Object ServiceAspect(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("MyAspect.ServiceAspect");
Object ret=joinPoint.proceed();
return ret;
}
}
3.在Spring配置文件中声明对应的原始类和增强类
<bean id="AspectService" class="org.Aspect.UserServiceImpl"/>
<bean id="AspectCP" class="org.Aspect.MyAspect"/>
然后把它组装起来
<aop:aspectj-autoproxy/>
4.测试
public class TestAspect {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("/ApplicationContext.XML");
UserService userService= (UserService) context.getBean("AspectService");
userService.login("SY","1223456");
userService.register(new User());
}
可以看到都被代理了
3.如果有多个增强方法且不同的切入点表达式那么怎么统一管理?
需要使用@Pointcut注解
在增强方法之前声明@Pointcut
添加一个方法不需要实现如何东西,在@Pointcut的括号中添加表达式
@Pointcut()
public void Expres(){
}
例如:
分别为所有register方法和任意方法
@Pointcut("execution(* register(..))")
public void Expres1(){
}
@Pointcut("execution(* *(..))")
public void Expres2(){
}
增强方法的实现只需要在@Around()中填写上注解即可
完整代码如下
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AspectAnn {
@Pointcut("execution(* register(..))")
public void Expres1(){
}
@Pointcut("execution(* *(..))")
public void Expres2(){
}
@Around("Expres1()")
public Object CPannotation1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("AspectAnn.CPannotation1");
Object ret= proceedingJoinPoint.proceed();
return ret;
}
@Around("Expres2()")
public Object CPannotation2(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("AspectAnn.CPannotation2");
Object ret= proceedingJoinPoint.proceed();
return ret;
}
}
在配置文件中声明下
<bean id="AnnAspect" class="org.Aspect.AspectAnn"/>
执行测试