Spring AOP--静态代理、动态代理、cglib代理、多切面顺序控制笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunshine_YG/article/details/82705170

代理:通过代理对象访问目标对象,这样可以在目标对象实现的基础上,增强额外的功能操作(即扩展目标对象的功能)。

简言之,在调用目标对象的方法前后做一些操作,以达到增强的目的。

注意:类内部自调用不会触发AOP。

动物类接口:

public interface Animal {
    void call();
}

小狗类

public class Dog implements Animal {
    @Override
    public void call() {
        System.out.println("汪汪");
    }
}

小猫类

public class Cat implements Animal {
    @Override
    public void call() {
        System.out.println("喵喵");
    }
}

静态代理

动物代理类

public class AnimalProxy implements Animal {
    private Animal animal;

    public AnimalProxy(Animal animal){
        this.animal=animal;
    }
    @Override
    public void call() {
        System.out.println("没有bug的宁静的夜晚,一切都那么和谐,突然听到了一声");
        animal.call();
        System.out.println("原来是一只"+this.animal.getClass().getSimpleName()+",真可爱啊");
    }
}

测试类:

public class TestProxy {

    //静态代理
    @Test
    public void testStaticProxy(){
        Dog dog=new Dog();
        AnimalProxy animalProxy=new AnimalProxy(dog);
        animalProxy.call();
    }
}

动态代理

动态动物代理类

public class DynamicAnimalProxy implements InvocationHandler {

    private Animal animal;

    public DynamicAnimalProxy(Animal animal){
        this.animal=animal;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("就像");
        method.invoke(animal,args);
        System.out.println("一样");
        return null;
    }
}

测试类

public class TestProxy {

    //静态代理
    @Test
    public void testStaticProxy() {
        Dog dog = new Dog();
        AnimalProxy animalProxy = new AnimalProxy(dog);
        animalProxy.call();
    }

    @Test
    public void testDynamicProxy() {
        Cat cat = new Cat();
        DynamicAnimalProxy dynamicAnimalProxy = new DynamicAnimalProxy(cat);
        ClassLoader classLoader = cat.getClass().getClassLoader();
        Animal animal = (Animal) Proxy.newProxyInstance(classLoader, cat.getClass().getInterfaces(), dynamicAnimalProxy);
        animal.call();
    }
}

cglib代理

注解方式:

@RestController
public class DogController {

    @Resource
    private Animal dog;

    @RequestMapping(value = "/dogCall",method = RequestMethod.GET)
    public JsonData dogCall(String name){
        dog.call();
        return JsonData.success();
    }
}

@Aspect
@Component("myAspect")
public class MyAspect {

    // * 表示任意返回类型  (..) 表示匹配任意参数
    @Pointcut("execution(* com.sunshine.shine.Service.impl.Dog.call(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(){
        System.out.println("before------");
    }

    @Around("pointCut()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("around before------");
        joinPoint.proceed(); //执行被加强的方法
        System.out.println("around after------");

    }

    @After("pointCut()")
    public void after(){
        System.out.println("after-------");
    }

    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("afterReturn-----");
    }

    @AfterThrowing("pointCut()")
    public void afterThrowing(){
        System.out.println("afterThrowing----");
    }

}

运行程序,请求 /dogCall,结果如下

around before------
before------
汪汪
around after------
after-------
afterReturn-----

XML配置文件方式:

 <bean id="aspectXml" class="com.sunshine.shine.Proxys.MyAspectXml" />

    <aop:aspectj-autoproxy proxy-target-class="true" />

    <aop:config>
        <aop:aspect id="aspect" ref="aspectXml">
            <aop:pointcut expression="execution(* com.sunshine.shine.Service.impl.Dog.call(..))" id="refcall" />
            <aop:before method="before" pointcut-ref="refcall" />
            <aop:after-returning method="afterReturning" pointcut-ref="refcall" />
            <aop:after-throwing method="afterThrowing" pointcut-ref="refcall" />
            <aop:around method="around" pointcut-ref="refcall" />
            <aop:after method="after" pointcut-ref="refcall"/>
        </aop:aspect>
    </aop:config>

public class MyAspectXml {

    public void before(){
        System.out.println("before------");
    }


    public void around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("around before------");
        joinPoint.proceed();//执行被加强的方法
        System.out.println("around after------");

    }

    public void after(){
        System.out.println("after-------");
    }


    public void afterReturning(){
        System.out.println("afterReturn-----");
    }


    public void afterThrowing(){
        System.out.println("afterThrowing----");
    }

}

运行程序,请求 /dogCall,结果如下

before------
around before------
汪汪
after-------
around after------
afterReturn-----

 

总结:

注解方式执行顺序:

around before

before

执行方法

around after

after

afterReturning

XML文件配置方式执行顺序:

before

around before

执行方法

after

around after

afterReturning

多切面顺序控制

原切面加个顺序  @Order(1)


@Order(1)
@Aspect
@Component("myAspect")
public class MyAspect {

//    @DeclareParents(value = "com.sunshine.shine.Service.impl.Dog+",defaultImpl = AnimalServiceImpl.class)
//    public AnimalService animalService;


    @Pointcut("execution(* com.sunshine.shine.Service.impl.Dog.call(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(){
        System.out.println("before------");
    }

    @Around("pointCut()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("around before------");
        joinPoint.proceed();
        System.out.println("around after------");

    }

    @After("pointCut()")
    public void after(){
        System.out.println("after-------");
    }

    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("afterReturn-----");
    }

    @AfterThrowing("pointCut()")
    public void afterThrowing(){
        System.out.println("afterThrowing----");
    }

}

再添加两个相同的切面  

@Aspect
@Component
public class MyAspect2 implements Ordered {

//    @DeclareParents(value = "com.sunshine.shine.Service.impl.Dog+",defaultImpl = AnimalServiceImpl.class)
//    public AnimalService animalService;


    @Pointcut("execution(* com.sunshine.shine.Service.impl.Dog.call(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(){
        System.out.println("2before------");
    }

    @Around("pointCut()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("2around before------");
        joinPoint.proceed();
        System.out.println("2around after------");

    }

    @After("pointCut()")
    public void after(){
        System.out.println("2after-------");
    }

    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("2afterReturn-----");
    }

    @AfterThrowing("pointCut()")
    public void afterThrowing(){
        System.out.println("2afterThrowing----");
    }

    @Override
    public int getOrder() {
        return -1;
    }
}
@Order(0)
@Aspect
@Component
public class MyAspect3 {

//    @DeclareParents(value = "com.sunshine.shine.Service.impl.Dog+",defaultImpl = AnimalServiceImpl.class)
//    public AnimalService animalService;


    @Pointcut("execution(* com.sunshine.shine.Service.impl.Dog.call(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(){
        System.out.println("3before------");
    }

    @Around("pointCut()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("3around before------");
        joinPoint.proceed();
        System.out.println("3around after------");

    }

    @After("pointCut()")
    public void after(){
        System.out.println("3after-------");
    }

    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("3afterReturn-----");
    }

    @AfterThrowing("pointCut()")
    public void afterThrowing(){
        System.out.println("3afterThrowing----");
    }

}

运行结果(类似责任链):

2around before------
2before------
3around before------
3before------
around before------
before------
汪汪
around after------
after-------
afterReturn-----
3around after------
3after-------
3afterReturn-----
2around after------
2after-------
2afterReturn-----
运用了两种实现控制顺序方式:

1、@Order

2、implement Ordered

    @Override
    public int getOrder() {
        return -1;
    }
MyAspect  Order值为  1
MyAspect2 Order值为  -1
MyAspect3 Order值为 0

-1<0<1

所以顺序为  2 -> 3 -> 1

猜你喜欢

转载自blog.csdn.net/sunshine_YG/article/details/82705170
今日推荐