给出了 Spring1.2旧式AOP (基于dtd)实现的示例。
虽然在Spring 3中受支持,但advice使用在下一页将要学习的将Spring aop与AspectJ一起使用。
spring1.2旧式aop实现中支持4种类型的Advice。
Before Advice,在实际方法调用之前执行。 After Advice,在实际方法调用之后执行。如果方法返回值,则在返回值后执行。 Around Advice,它在实际方法调用之前和之后执行。 Throws Advice,如果实际方法引发异常,则执行该Advice。
让我们通过以下图表了解Advice层次结构:
所有都是aop中的接口。
MethodBeforeAdvice 接口扩展了 BeforeAdvice 接口。
AfterReturningAdvice 接口扩展了 AfterAdvice 接口。
ThrowsAdvice 接口扩展 AfterAdvice 接口。
MethodInterceptor 接口扩展 Interceptor 接口。它用于Advice周围。
1、MethodBeforeAdvice示例
创建一个包含实际业务逻辑的类。
文件: A.java
package com.nhooo;
public class A {
public void m(){System.out.println("actual business logic");}
}
现在,创建实现MethodBeforeAdvice接口的顾问程序类。
文件: BeforeAdvisor.java
package com.nhooo;
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 类。
文件: applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="obj" class="com.nhooo.A"></bean> <bean id="ba" class="com.nhooo.BeforeAdvisor"></bean> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="obj"></property> <property name="interceptorNames"> <list> <value>ba</value> </list> </property> </bean> </beans>
理解ProxyFactoryBean类:
ProxyFactoryBean 类由Spring Famework提供。它包含2个属性target和interceptorNames。 A类的实例将被视为目标对象,顾问类的实例将被视为拦截器。您需要像上面给出的xml文件中那样将顾问程序对象作为列表对象传递。
ProxyFactoryBean类的编写如下:
public class ProxyFactoryBean{
private Object target;
private List interceptorNames;
//getters and setters
}
现在,让我们调用实际方法。
文件: Test.java
package com.nhooo;
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();
}
}
输出
additional concern before actual logic actual business logic
在MethodBeforeAdvice中打印其他信息,我们可以打印其他信息,例如方法名称,方法参数,目标对象,目标对象类名称,代理类等。
您只需要更改两个类BeforeAdvisor.java和Test.java。
文件: BeforeAdvisor.java
package com.nhooo;
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());
}
}
文件: Test.java
package com.nhooo;
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();
}
}
输出
proxy class name: com.nhooo.A$EnhancerByCGLIB$409872b1 additional concern before actual logic method info:m 1 argument info: target Object:com.nhooo.A@11dba45 target object class name: com.nhooo.A actual business logic
AfterReturningAdvice示例
创建一个包含实际业务逻辑的类。
文件: A.java
与前面的示例相同。
现在,创建实现AfterReturningAdvice接口的顾问类。
文件: AfterAdvisor.java
package com.nhooo;
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文件,您只需要在此处更改顾问程序类。
文件: applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="obj" class="com.nhooo.A"></bean> <bean id="ba" class="com.nhooo.AfterAdvisor"></bean> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="obj"></property> <property name="interceptorNames"> <list> <value>ba</value> </list> </property> </bean> </beans>
文件: Test.java
与前面的示例相同。
输出
actual business logic additional concern after returning advice
3)MethodInterceptor(AroundAdvice)示例
创建一个包含实际业务逻辑的类。
文件: A。 java
与前面的示例相同。
现在,创建实现MethodInterceptor接口的顾问类。
文件: AroundAdvisor.java
package com.nhooo;
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文件,您只需要在此处更改顾问程序类。
文件: applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="obj" class="com.nhooo.A"></bean> <bean id="ba" class="com.nhooo.AroundAdvisor"></bean> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="obj"></property> <property name="interceptorNames"> <list> <value>ba</value> </list> </property> </bean> </beans>
文件: Test.java
与前面的示例相同。
输出
additional concern before actual logic actual business logic additional concern after actual logic
4、ThrowsAdvice示例
创建一个包含实际业务逻辑的类。
文件: Validator.java
package com.nhooo;
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接口的顾问程序类。
文件: ThrowsAdvisor.java
package com.nhooo;
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类。
文件: applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="obj" class="com.nhooo.Validator"></bean> <bean id="ba" class="com.nhooo.ThrowsAdvisor"></bean> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="obj"></property> <property name="interceptorNames"> <list> <value>ba</value> </list> </property> </bean> </beans>
文件: Test.java
package com.nhooo;
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();}
}
}
输出
java.lang.ArithmeticException: Not Valid Age additional concern if exception occurs at com.nhooo.Validator.validate(Validator.java:7) at com.nhooo.Validator$FastClassByCGLIB$562915cf.invoke(<generated>) at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invoke Joinpoint(Cglib2AopProxy.java:692) at org.springframework.aop.framework.ReflectiveMethodInvocation. proceed(ReflectiveMethodInvocation.java:150) at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor. invoke(ThrowsAdviceInterceptor.java:124) at org.springframework.aop.framework.ReflectiveMethodInvocation. proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor. intercept(Cglib2AopProxy.java:625) at com.nhooo.Validator$EnhancerByCGLIB$4230ed28.validate(<generated>) at com.nhooo.Test.main(Test.java:15)