在上文 Spring学习:AOP思想中已经介绍了,AOP思想,以及springAOP的初步使用方法。在上文中,所介绍到的MethodBeforeAdvice是为代理对象的每个方法执行前执行用户验证。那么现在就有一个问题,如果只是business1()和business2()执行前需要用户验证,我们应该怎么做?下面来介绍。
回顾一下上次的内容,有一个component类继承了Icomponent接口,并实现了接口的三个业务逻辑business1(),business2(),business3()我们希望在每个方法执行前调用用户验证。
//Icomponent接口
package com.cst.spring.lab3;
public interface Icomponent {
public void business1();
public void business2();
public void business3();
}
//component类
package com.cst.spring.lab3;
/**
* @author Cst
*
*/
public class Component implements Icomponent{
public void business1()
{
System.out.println("业务1");
}
public void business2()
{
System.out.println("业务2");
}
public void business3()
{
System.out.println("业务3");
}
}
我们可以通过实现MethodBeforeAdvice接口来实现所需要的要求,详看上文。
那么现在我们只需要为business1()执行前执行用户验证,怎么做?
Spring内建的Pointcut都有对应的PointcutAdvisor,
使用org.springframework.aop.support.NameMatchMethodPointcutAdvisor提供静态的Pointcut实例,使用表达式指定Advice应用目标上的方法名称,或者用*来指定。
1.实现MethodBeforeAdvice接口实现ValidateBeforeMethod类
public class ValidateBeforeMethod implements MethodBeforeAdvice{
public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
// TODO Auto-generated method stub
this.validate();
System.out.println(arg0);
}
public void validate()
{
System.out.println("验证用户");
}
}
2.配置xml
<bean id="component" class="com.cst.spring.lab3.Component"/>
<bean id="componentadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedName" value="*business1"/>
<property name="advice" ref="validatebeforeadvice"/>
bean>
<bean id="componentproxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="com.cst.spring.lab3.Icomponent"/>
<property name="target" ref="component"/>
<property name="interceptorNames">
<list>
<value>componentadvisorvalue>
list>
property>
bean>
3.测试类
public class AopExample {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Icomponent icom=(Icomponent)context.getBean("componentproxy");
icom.business1();
}
}
如果需要为busines1()和business2()又如何做?
Spring 提供org.springframework.aop.support.RegexpMethodPointcutAdvisor
使用正则表达式来编写Pointcut表达式,其值为“pattern”属性值。
<bean id="componentadvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="pattern" value=".*business(1|2)"/>
<property name="advice" ref="validatebeforeadvice"/>
bean>
在Spring中,Introduction是一种特殊的Advice,直接介入整个对象的行为,好像对象凭空多了可操作的行为,为对象动态加入原先所没有的职责。
可以通过实现org.springframework.aop.IntroductionInterceptor来实现Introduction
在不修改原始文件的情况下,
将增加的可操作方法放在另一接口中将Introduction织入到目标对象上,使用org.springframework.aop.support.DefaultIntroductionAdvisor
也就是说我们可以将用户验证方法使用Introduction织入到目标对象中。实现如下
1.定义用户验证接口类
public interface IValidate {
public void Validate();
}
2.实现Introduction
//实现了接口Ivalidate与IntroductionInterceptor
public class ValidateIntroduction implements IValidate, IntroductionInterceptor {
public Object invoke(MethodInvocation arg0) throws Throwable {
if(implementsInterface(arg0.getMethod().getDeclaringClass()))
{
return arg0.getMethod().invoke(this, arg0.getArguments());
}
else
{
return arg0.proceed();
}
}
//判断是否继承验证接口
public boolean implementsInterface(Class arg0) {
return arg0.isAssignableFrom(IValidate.class);
}
public void Validate() {
System.out.println("用户验证");
}
}
3.配置xml文件
<bean id="component" class="com.cst.spring.lab3.Component"/>
<bean id="validateintroduction" class="com.cst.spring.lab3.ValidateIntroduction"/>
<bean id="validateAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg ref="validateintroduction"/>
<constructor-arg value="com.cst.spring.lab3.IValidate"/>
bean>
<bean id="componentproxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="com.cst.spring.lab3.Icomponent"/>
<property name="target" ref="component"/>
<property name="interceptorNames">
<list>
<value>validateAdvisorvalue>
list>
property>
bean>
4.测试类
public class AopExample {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Icomponent icom=(Icomponent)context.getBean("component");
((IValidate)icom).Validate();
icom.business1();
((IValidate)icom).Validate();
icom.business2();
}
}
以上便实现了使用Introduction在business1(),business2()前进行用户验证。
利用BeanNameAutoProxyCreator完成自动代理。
<bean id="component" class="com.cst.spring.lab3.Component"/>
<bean id="validateintroduction" class="com.cst.spring.lab3.ValidateIntroduction"/>
<bean id="validateAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg ref="validateintroduction"/>
<constructor-arg value="com.cst.spring.lab3.IValidate"/>
bean>
<bean id="introductionproxycreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>componentvalue>
list>
property>
<property name="interceptorNames" value="validateAdvisor"/>
bean>
测试类如上。
以上便是本文的全部内容。有错误请指出,谢谢