- Before Advice示例
- After Returning Advice的示例
- Around Advice示例
- After Throwing Advice的示例
给出了Spring1.2旧式AOP(基于dtd)实现的示例。
虽然它在spring 3中受支持, 但是Advice将Spring aop与我们将在下一页中学习的AspectJ一起使用。
spring1.2旧式aop实现中支持4种类型的Advice。
- 在Before Advice, 它在实际方法调用之前执行。
- 在After Advice, 它在实际方法调用之后执行。如果方法返回值, 则在返回值后执行。
- 在Advice周围, 它在实际方法调用之前和之后执行。
- 如果实际方法抛出异常, 则执行Throws Advice。
要了解Spring AOP的基本概念, 请访问上一页。
了解Advice界面的层次结构
让我们通过下面的图表了解Advice层次结构:
都是aop中的接口。
MethodBeforeAdvice接口扩展了BeforeAdvice接口。
AfterReturningAdvice接口扩展了AfterAdvice接口。
ThrowsAdvice接口扩展了AfterAdvice接口。
MethodInterceptor接口扩展了Interceptor接口。它在Around Advice使用。
1)MethodBeforeAdvice示例
创建一个包含实际业务逻辑的类。
档案:A.java
package com.srcmini;
public class A {
public void m(){System.out.println("actual business logic");}
}
现在, 创建实现MethodBeforeAdvice接口的顾问类。
文件:BeforeAdvisor.java
package com.srcmini;
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.srcmini.A"></bean>
<bean id="ba" class="com.srcmini.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.srcmini;
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();
}
}
输出
实际逻辑之前的附加关注
在MethodBeforeAdvice中打印其他信息
我们可以打印其他信息, 例如方法名称, 方法参数, 目标对象, 目标对象类名称, 代理类等。
你只需要更改两个类BeforeAdvisor.java和Test.java。
文件:BeforeAdvisor.java
package com.srcmini;
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.srcmini;
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();
}
}
输出
代理类名称:com.srcmini.A $$ EnhancerByCGLIB $$ 409872b1在实际逻辑方法信息之前附加的关注点:m 1参数信息:target Object:com.srcmini.A@11dba45目标对象类名称:com.srcmini.A实际业务逻辑
2)AfterReturningAdvice示例
创建一个包含实际业务逻辑的类。
档案:A.java
与前面的示例相同。
现在, 创建实现AfterReturningAdvice接口的顾问类。
文件:AfterAdvisor.java
package com.srcmini;
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类。
文件: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.srcmini.A"></bean>
<bean id="ba" class="com.srcmini.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
与前面的示例相同。
输出
After Returning Advice, 实际的业务逻辑需要额外关注
3)MethodInterceptor(AroundAdvice)示例
创建一个包含实际业务逻辑的类。
档案:A.java
与前面的示例相同。
现在, 创建实现MethodInterceptor接口的顾问程序类。
文件:AroundAdvisor.java
package com.srcmini;
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类。
文件: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.srcmini.A"></bean>
<bean id="ba" class="com.srcmini.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
与前面的示例相同。
输出
在实际逻辑之前附加关注实际业务逻辑在实际逻辑之后附加关注
4)ThrowsAdvice示例
创建一个包含实际业务逻辑的类。
文件:Validator.java
package com.srcmini;
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.srcmini;
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.srcmini.Validator"></bean>
<bean id="ba" class="com.srcmini.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.srcmini;
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:无效如果在com.srcmini.Validator $$ FastClassByCGLIB $$ 562915cf.invoke(<netned>)上的com.srcmini.Validator.validate(Validator.java:7)发生异常, 则还要额外考虑年龄.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)位于org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invoke Joinpoint(Cglib2AopProxy.java:692)位于org.springframework.aop.framework.ReflectiveMethodInvocation。在org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor处继续(ReflectiveMethodInvocation.java:150)。在org.springframework.aop.framework.ReflectiveMethodInvocation上调用(ThrowsAdviceInterceptor.java:124)。在org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor处继续(ReflectiveMethodInvocation.java:172)。在com.srcmini.Validator $$ EnhancerByCGLIB $$ 4230ed28.validate(<generated())在com.srcmini.Test.main(Test.java:15)处拦截(Cglib2AopProxy.java:625)
评论前必须登录!
注册