📜  Spring AOP示例

📅  最后修改于: 2020-12-04 07:52:23             🧑  作者: Mango

Spring AOP示例

给出了Spring1.2旧式AOP (基于dtd)实现的示例。

虽然它在spring 3中受支持,但是建议将Spring aop与我们将在下一页中学习的AspectJ一起使用。

spring1.2旧式aop实现中支持4种类型的建议。

  • 在建议之前,它在实际方法调用之前执行。
  • 在建议之后,它在实际方法调用之后执行。如果方法返回值,则在返回值后执行。
  • 在Advice周围,它在实际方法调用之前和之后执行。
  • 如果实际方法抛出异常,则执行建议。

要了解Spring AOP的基本概念,请访问上一页。

了解建议界面的层次结构

让我们通过以下图表了解建议层次结构:

所有都是aop中的接口。

MethodBeforeAdvice接口扩展了BeforeAdvice接口。

AfterReturningAdvice接口扩展了AfterAdvice接口。

ThrowsAdvice接口扩展了AfterAdvice接口。

MethodInterceptor接口扩展了Interceptor接口。它在建议周围使用。

1)MethodBeforeAdvice示例

创建一个包含实际业务逻辑的类。

package com.javatpoint;
public class A {
public void m(){System.out.println("actual business logic");}
}

现在,创建实现MethodBeforeAdvice接口的顾问程序类。

package com.javatpoint;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdvisor implements MethodBeforeAdvice{
    @Override
    public void before(Method method, Object[] args, Object target)throws Throwable {
        System.out.println("additional concern before actual logic");
    }
}

在xml文件中,创建3个bean,一个用于A类,第二个用于Advisor类,第三个用于ProxyFactoryBean类。











ba





了解ProxyFactoryBean类:

ProxyFactoryBean类由Spring Famework提供。它包含2个属性target和interceptorNames。 A类的实例将被视为目标对象,顾问类的实例将被视为拦截器。您需要像上面给出的xml文件中那样将顾问程序对象作为列表对象传递。

ProxyFactoryBean类的编写如下:

public class ProxyFactoryBean{
private Object target;
private List interceptorNames;
//getters and setters
}

现在,让我们调用实际方法。

package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
    Resource r=new ClassPathResource("applicationContext.xml");
    BeanFactory factory=new XmlBeanFactory(r);
    
    A a=factory.getBean("proxy",A.class);
    a.m();
}
}

输出量

  1. additional concern before actual logic  
  2. actual business logic  

在MethodBeforeAdvice中打印其他信息

我们可以print其他信息,例如方法名称,方法参数,目标对象,目标对象类名称,代理类等。

您只需要更改两个类BeforeAdvisor.java和Test.java。

package com.javatpoint;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class BeforeAdvisor implements MethodBeforeAdvice{
    @Override
    public void before(Method method, Object[] args, Object target)throws Throwable {
        System.out.println("additional concern before actual logic");
        System.out.println("method info:"+method.getName()+" "+method.getModifiers());
        System.out.println("argument info:");
        for(Object arg:args)
            System.out.println(arg);
        System.out.println("target Object:"+target);
        System.out.println("target object class name: "+target.getClass().getName());
    }
}
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
    Resource r=new ClassPathResource("applicationContext.xml");
    BeanFactory factory=new XmlBeanFactory(r);
    
    A a=factory.getBean("proxy",A.class);
        System.out.println("proxy class name: "+a.getClass().getName());
    a.m();
}
}

输出量

  1. proxy class name: com.javatpoint.A$$EnhancerByCGLIB$$409872b1  
  2. additional concern before actual logic  
  3. method info:m 1  
  4. argument info:  
  5. target Object:com.javatpoint.A@11dba45  
  6. target object class name: com.javatpoint.A  
  7. actual business logic  

2)AfterReturningAdvice示例

创建一个包含实际业务逻辑的类。

与前面的示例相同。

现在,创建实现AfterReturningAdvice接口的顾问类。

package com.javatpoint;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterAdvisor implements AfterReturningAdvice{
    @Override
    public void afterReturning(Object returnValue, Method method,
         Object[] args, Object target) throws Throwable {
        
        System.out.println("additional concern after returning advice");
    }

}

如前面的示例中那样创建xml文件,您只需要在这里更改Advisor类。











ba





与前面的示例相同。

输出量

  1. actual business logic  
  2. additional concern after returning advice  

3)MethodInterceptor(AroundAdvice)示例

创建一个包含实际业务逻辑的类。

与前面的示例相同。

现在,创建实现MethodInterceptor接口的顾问类。

package com.javatpoint;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdvisor implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object obj;
        System.out.println("additional concern before actual logic");
        obj=mi.proceed();
        System.out.println("additional concern after actual logic");
        return obj;
    }

}

如前面的示例中那样创建xml文件,您只需要在这里更改Advisor类。











ba





与前面的示例相同。

输出量

  1. additional concern before actual logic  
  2. actual business logic  
  3. additional concern after actual logic  

4)ThrowsAdvice示例

创建一个包含实际业务逻辑的类。

package com.javatpoint;
public class Validator {
    public void validate(int age)throws Exception{
        if(age<18){
            throw new ArithmeticException("Not Valid Age");
        }
        else{
            System.out.println("vote confirmed");
        }
    }
}

现在,创建实现ThrowsAdvice接口的顾问类。

package com.javatpoint;
import org.springframework.aop.ThrowsAdvice;
public class ThrowsAdvisor implements ThrowsAdvice{
    public void afterThrowing(Exception ex){
        System.out.println("additional concern if exception occurs");
    }
}

如前面的示例一样,创建xml文件,您只需要更改Validator类和Advisor类。











ba





package com.javatpoint;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Test {
public static void main(String[] args) {
    Resource r=new ClassPathResource("applicationContext.xml");
    BeanFactory factory=new XmlBeanFactory(r);
    
    Validator v=factory.getBean("proxy",Validator.class);
    try{
    v.validate(12);
    }catch(Exception e){e.printStackTrace();}
}
}

输出量

  1. java.lang.ArithmeticException: Not Valid Age  
  2.   
  3. additional concern if exception occurs  
  4.   
  5.     at com.javatpoint.Validator.validate(Validator.java:7)  
  6.     at com.javatpoint.Validator$$FastClassByCGLIB$$562915cf.invoke()  
  7.     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)  
  8.     at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invoke  
  9. Joinpoint(Cglib2AopProxy.java:692)  
  10.     at org.springframework.aop.framework.ReflectiveMethodInvocation.  
  11. proceed(ReflectiveMethodInvocation.java:150)  
  12.     at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.  
  13. invoke(ThrowsAdviceInterceptor.java:124)  
  14.     at org.springframework.aop.framework.ReflectiveMethodInvocation.  
  15. proceed(ReflectiveMethodInvocation.java:172)  
  16.     at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.  
  17. intercept(Cglib2AopProxy.java:625)  
  18.     at com.javatpoint.Validator$$EnhancerByCGLIB$$4230ed28.validate()  
  19.     at com.javatpoint.Test.main(Test.java:15)