使用注解对Spring动态代理进行开发

使用注解对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());
    }

可以看到都被代理了

image-20210601192452969

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"/>

执行测试

image-20210601193548572

posted on 2021-06-01 20:14  NathenJames  阅读(278)  评论(0编辑  收藏  举报