Spring使用指南 ~ 5Spring AOP 使用简介

Posted 戴泽supp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring使用指南 ~ 5Spring AOP 使用简介相关的知识,希望对你有一定的参考价值。

Spring AOP 使用简介

一、通知(Advice)

公共使用类 Agent.java

package com.luo.spring.guides.aop.simple.domain;

public class Agent 
    public void speak() 
        System.out.println("Bond");
    

1、前置通知

package com.luo.spring.guides.aop.simple.beforeadvice;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class SimpleBeforeAdvice implements MethodBeforeAdvice 
    @Override
    public void before(Method method, Object[] args, Object target)
            throws Throwable 
        System.out.println("Before method: " + method);
    

测试

package com.luo.spring.guides.aop.simple.beforeadvice;

import com.luo.spring.guides.aop.simple.domain.Agent;
import org.springframework.aop.framework.ProxyFactory;

/**
 * @author : archer
 * @date : Created in 2022/12/12 14:55
 * @description :
 */
public class Main 

    public static void main(String... args) 
        Agent target = new Agent();

        ProxyFactory pf = new ProxyFactory();
        pf.addAdvice(new SimpleBeforeAdvice());
        pf.setTarget(target);

        Agent proxy = (Agent) pf.getProxy();

        System.out.println("");
        proxy.speak();
    

输出

Before method: public void com.luo.spring.guides.aop.simple.domain.Agent.speak()
Bond

2、后置返回通知

package com.luo.spring.guides.aop.simple.afterreturningadvice;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class SimpleAfterReturningAdvice implements AfterReturningAdvice 

    @Override
    public void afterReturning(Object returnValue, Method method, 
             Object[] args, Object target) throws Throwable 
        System.out.println("After return:" + method.getName());
    

测试

package com.luo.spring.guides.aop.simple.afterreturningadvice;

import com.luo.spring.guides.aop.simple.domain.Agent;
import org.springframework.aop.framework.ProxyFactory;

/**
 * @author : archer
 * @date : Created in 2022/12/12 14:55
 * @description :
 */
public class Main 

    public static void main(String... args) 
        Agent target = new Agent();

        ProxyFactory pf = new ProxyFactory();
        pf.addAdvice(new SimpleAfterReturningAdvice());
        pf.setTarget(target);

        Agent proxy = (Agent) pf.getProxy();
        proxy.speak();
    

输出

Bond
After return:speak

3、环绕通知

package com.luo.spring.guides.aop.simple.aroundadvice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class SimpleAroundAdvice implements MethodInterceptor 
    public Object invoke(MethodInvocation invocation) throws Throwable 
        System.out.println("before");

        Object proceed = invocation.proceed();

        System.out.println("after");

        return proceed;
    

测试

package com.luo.spring.guides.aop.simple.aroundadvice;

import com.luo.spring.guides.aop.simple.domain.Agent;
import org.springframework.aop.framework.ProxyFactory;

/**
 * @author : archer
 * @date : Created in 2022/12/12 14:55
 * @description :
 */
public class Main 

    public static void main(String... args) 
        Agent target = new Agent();

        ProxyFactory pf = new ProxyFactory();
        pf.addAdvice(new SimpleAroundAdvice());
        pf.setTarget(target);

        Agent proxy = (Agent) pf.getProxy();

        proxy.speak();
    

输出

before
Bond
after

4、异常通知

  • 如果异常类型相同,Spring 优先使用参数多个那个
package com.luo.spring.guides.aop.simple.domain;

public class ErrorBean 
    public void errorMethod() throws Exception 
        throw new Exception("Generic Exception");
    

    public void otherErrorMethod() throws IllegalArgumentException 
        throw new IllegalArgumentException("IllegalArgument Exception");
    

package com.luo.spring.guides.aop.simple.throwsadvice;

import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

public class SimpleThrowsAdvice implements ThrowsAdvice 


    public void afterThrowing(Exception ex) throws Throwable 
        System.out.println("***");
        System.out.println("Generic Exception Capture");
        System.out.println("Caught: " + ex.getClass().getName());
        System.out.println("***\\n");
    

    //如果异常类型相同,Spring 优先使用参数多个那个
    public void afterThrowing(Method method, Object[] args, Object target, IllegalArgumentException ex) throws Throwable 
        System.out.println("***");
        System.out.println("IllegalArgumentException Capture");
        System.out.println("Caught: " + ex.getClass().getName());
        System.out.println("Method: " + method.getName());
        System.out.println("***\\n");
    

测试

package com.luo.spring.guides.aop.simple.throwsadvice;

import com.luo.spring.guides.aop.simple.domain.ErrorBean;
import org.springframework.aop.framework.ProxyFactory;

/**
 * @author : archer
 * @date : Created in 2022/12/12 15:23
 * @description :
 */
public class Main 
    public static void main(String... args) throws Exception 
        ErrorBean errorBean = new ErrorBean();

        ProxyFactory pf = new ProxyFactory();
        pf.setTarget(errorBean);
        pf.addAdvice(new SimpleThrowsAdvice());

        ErrorBean proxy = (ErrorBean) pf.getProxy();

        try 
            proxy.errorMethod();
         catch (Exception ignored) 

        

        try 
            proxy.otherErrorMethod();
         catch (Exception ignored) 

        
    

输出

******
Generic Exception Capture
Caught: java.lang.Exception
******

******
IllegalArgumentException Capture
Caught: java.lang.IllegalArgumentException
Method: otherErrorMethod
******

二、切入点(Pointcut)

切入点:可以看成判断是否触发通知代理类的条件规则

通用接口

package com.luo.spring.guides.aop.pointcut.statics.domain;

/**
 * Created by iuliana.cosmina on 4/2/17.
 */
public interface Singer 
	void sing();

1、静态切入点

  • 静态切入点只能把被代理类的的一些静态信息(如类名称,方法名称等),作为判断条件

被代理类

package com.luo.spring.guides.aop.pointcut.statics.domain;


/**
 * Created by iuliana.cosmina on 4/2/17.
 */
public class GoodGuitarist implements Singer 

	@Override public void sing() 
		System.out.println("Who says I can't be free \\n" +
				"From all of the things that I used to be");
	

package com.luo.spring.guides.aop.pointcut.statics.domain;


/**
 * Created by iuliana.cosmina on 4/2/17.
 */
public class GreatGuitarist implements Singer 

	@Override public void sing() 
		System.out.println("I shot the sheriff, \\n" +
				"But I did not shoot the deputy");
	

通知类

package com.luo.spring.guides.aop.pointcut.statics.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class SimpleAdvice implements MethodInterceptor 
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable 
        System.out.println(">> Invoking " + invocation.getMethod().getName());
        Object retVal = invocation.proceed();
        System.out.println(">> Done\\n");
        return retVal;
    

切入点

  • 有很多判断条件,具体参考可重写父类方法
package com.luo.spring.guides.aop.pointcut.statics;

import com.luo.spring.guides.aop.pointcut.statics.domain.GoodGuitarist;
import org.springframework.aop.support.StaticMethodMatcherPointcut;

import java.lang.reflect.Method;
//有很多判断条件,具体参考可重写父类方法
public class SimpleStaticPointcut extends StaticMethodMatcherPointcut 
    @Override
    public boolean matches(Method method, Class<?> cls) 
        return ("sing".equals(method.getName())) && cls == GoodGuitarist.class;
    

//    @Override
//    public ClassFilter getClassFilter() 
//        ClassFilter classFilter = cls -> (cls == GoodGuitarist.class);
//        return classFilter;
//    

测试

package com.luo.spring.guides.aop.pointcut.statics;

import com.luo.spring.guides.aop.pointcut.statics.advice.SimpleAdvice;
import com.luo.spring.guides.aop.pointcut.statics.domain.GoodGuitarist;
import com.luo.spring.guides.aop.pointcut.statics.domain.GreatGuitarist;
import com.luo.spring.guides.aop.pointcut.statics.domain.Singer;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class Main 
    public static void main(String... args) 
        GoodGuitarist goodGuitarist = new GoodGuitarist();
        GreatGuitarist greatGuitarist = new GreatGuitarist();

        Singer proxyOne;
        Singer proxyTwo;

        Pointcut pc = new SimpleStaticPointcut();
        Advice advice = new SimpleAdvice();
        Advisor advisor = new DefaultPointcutAdvisor(pc, advice);

        ProxyFactory pf = new ProxyFactory();
        pf.addAdvisor(advisor);
        pf.setTarget(goodGuitarist);
        proxyOne = (Singer)pf.getProxy();

        pf = new ProxyFactory();
        pf.addAdvisor(advisor);
        pf.setTarget(greatGuitarist);
        proxyTwo = (Singer)pf.getProxy();

        proxyOne.sing();
        proxyTwo.sing();
    

输出

>> Invoking sing
Who says I can’t be free
From all of the things that I used to be
>> Done

I shot the sheriff,
But I did not shoot the deputy

2、动态切入点

  • 动态切入点相对于静态切入点,增加了对参数内容的条件判断
  • 增加了灵活性,降低了性能

被代理类

package com.luo.spring.guides.aop.pointcut.dyanmic;

public class SampleBean 
    public void foo(int x) 
        System.out.println("Invoked foo() with: " + x);
    

    public void bar() 
        System.out.println("Invoked bar()");
    

通知类

package com.luo.spring.guides.aop.pointcut.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class SimpleAdvice implements MethodInterceptor 
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable 
        System.out5Spring AOP的几种通知(xml)

Spring5Spring 简介

5Spring Boot缓存

5Spring 源码学习 ~ 默认标签 alias 标签的解析与注册

Spring_8-Spring事务管理

老王读Spring IoC-5Spring IoC 小结——控制反转依赖注入