1
下面看具体的例子:
定义Person接口,声明两个方法
package lee;
public interface Person {
void info();
void run();
}
具体的实现类
package lee;
public class PersonImpl implements Person {
private String name;
private int age;
public void info() {
System.out.println("我的名字是:"+name+",今年年龄为:"+age);
}
public void run() {
if(age > 45){
System.out.println("我年老体弱,只能慢跑");
}else{
System.out.println("我年轻体壮,可以快跑");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
下面定义三个拦截器
package lee;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvisor implements MethodBeforeAdvice {
public void before(Method m, Object[] arg, Object target)
throws Throwable {
System.out.println("方法调用前...");
System.out.println("下面是方法调用的信息...");
System.out.println("所执行的方法是..."+m);
System.out.println("调用方法的参数是..."+arg);
System.out.println("目标对象是..."+target);
}
}
package lee;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("调用方法之前:invocation对象:["+invocation+"]");
Object rval = invocation.proceed();
System.out.println("调用结束...");
return rval;
}
}
package lee;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class MyAfterAdvisor implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method m, Object[] args,
Object target) throws Throwable {
System.out.println("方法调用结束...");
System.out.println("目标方法的返回值是:..."+returnValue);
System.out.println("目标方法是..."+m);
System.out.println("目标方法的参数是..."+args);
System.out.println("目标对象是..."+target);
}
}
spring配置文件
<bean id="personTarget" class="lee.PersonImpl"> <property name="name"> <value>Wawa</value> </property> <property name="age"> <value>51</value> </property> </bean> <bean id="myBeforeAdvisor" class="lee.MyBeforeAdvisor"/> <bean id="myAroundAdvisor" class="lee.MyAroundInterceptor"/> <!-- 正则表达式横切点 --> <bean id="runAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!-- advice属性确定处理bean --> <property name="advice"> <!-- 此处的处理bean定义采用嵌套bean,也可引用容器的另一个bean --> <bean class="lee.MyAfterAdvisor"></bean> </property> <!-- patterns定义正则表达式 --> <property name="patterns"> <list> <!-- 确定正则表达式列表 --> <value>.*run.*</value> </list> </property> </bean> <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 定义需代理的接口 --> <property name="proxyInterfaces"> <value>lee.Person</value> </property> <!-- 定义要切入的对象 --> <property name="target"> <ref local="personTarget"/> </property> <!-- 使用以下三个拦截类切入 --> <property name="interceptorNames"> <list> <value>runAdvisor</value> <value>myBeforeAdvisor</value> <value>myAroundAdvisor</value> </list> </property> </bean>
测试类:
package lee;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BeanTest {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
Person p = (Person)factory.getBean("person");
p.run();
}
}
最后打印出
方法调用前... 下面是方法调用的信息... 所执行的方法是...public abstract void lee.Person.run() 调用方法的参数是...[Ljava.lang.Object;@184ec44 目标对象是...lee.PersonImpl@1b383e9 调用方法之前:invocation对象:[ReflectiveMethodInvocation: public abstract void lee.Person.run(); target is of class [lee.PersonImpl]] 我年老体弱,只能慢跑 调用结束... 方法调用结束... 目标方法的返回值是:...null 目标方法是...public abstract void lee.Person.run() 目标方法的参数是...[Ljava.lang.Object;@99681b 目标对象是...lee.PersonImpl@1b383e9
下面再看一个权限校验的例子:
package permission;
public interface TestService {
void view();
void modify();
}
package permission;
public class TestServiceImpl implements TestService {
public void modify() {
System.out.println("用户修改数据");
}
public void view() {
System.out.println("用户查看数据");
}
}
package permission;
public interface TestAction {
public void view();
public void modify();
}
package permission;
public class TestActionImpl implements TestAction {
private TestService ts;
public void modify() {
ts.modify();
}
public void view() {
ts.view();
}
public void setTs(TestService ts) {
this.ts = ts;
}
}
拦截类,这个类中会进行验权
package permission;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AuthorityInterceptor implements MethodInterceptor {
private String user;
public void setUser(String user) {
this.user = user;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("-------------------------");
String methodName = invocation.getMethod().getName();
if(!user.equals("admin") && !user.equals("registedUser")){
System.out.println("你无权执行该方法");
return null;
}else if(user.equals("registedUser") && methodName.equals("modify")){
System.out.println("你不是管理员,无法修改数据");
return null;
}else {
return invocation.proceed();
}
}
}
spring中的配置文件
<bean id="serviceTarget" class="permission.TestServiceImpl"/> <bean name="authorityInterceptor" class="permission.AuthorityInterceptor"> <property name="user"> <value>registedUser</value> </property> </bean> <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>permission.TestService</value> </property> <property name="target"> <ref local="serviceTarget"/> </property> <property name="interceptorNames"> <list> <value>authorityInterceptor</value> </list> </property> </bean> <bean id="testAction" class="permission.TestActionImpl"> <property name="ts"> <ref local="service"/> </property> </bean>
测试类
package permission;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BeanTest {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
TestAction ta = (TestAction)factory.getBean("testAction");
ta.modify();
ta.view();
}
}
结果打印:
------------------------- 你不是管理员,无法修改数据 ------------------------- 用户查看数据
这个例子属于功能增强的概念,将验权功能植入action类中。
如果没有接口,只有具体类应该怎么做?如只有TestServiceImpl类,没有TestService接口,那么应该如何拦截,
可在spring配置文件中将设置一个属性proxyTargetClass,将其值设为true,表示目标类是个具体类,如下粗体所示。
<bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyTargetClass"> <value>true</value> </property> <property name="target"> <ref local="serviceTarget"/> </property> <property name="interceptorNames"> <list> <value>authorityInterceptor</value> </list> </property> </bean>