spring AOP 通讯前置
- 实现思路:
前置通知Before Advice会在目标对象的方法执行前被调用,设计思路如下:
(1)设计一个接口。
作为代理对象的接口
public interface IComponent {
/**
* 业务接口 对应业务123
*/
public void bussiness1();
public void bussiness2();
public void bussiness3();
//public void validateUser();
}
(2)编写这个接口的实现。
实现接口中的业务代码,作为代理对象的类。
public class Component implements IComponent{
/**
* 代理的对象 为该类添加通讯前置方法
*/
@Override
public void bussiness1() {
//validateUser();
System.out.println("业务1....");
}
@Override
public void bussiness2() {
//validateUser();
System.out.println("业务2");
}
@Override
public void bussiness3() {
//validateUser();
System.out.println("业务3");
}
/*@Override
public void validateUser() {
// TODO Auto-generated method stub
System.out.println("验证业务");
}*/
}
(3)编写前置通知的逻辑代码,该代码必须实现MethodBeforeAdvice接口,需要前置的服务都写在这里。
所有需要前置的服务均写在before()方法体中,这里模拟验证用户的方法放到before()方法体中。
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class AdviceBeforeComponent implements MethodBeforeAdvice{
/**
* 通讯前置逻辑代码
*/
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// 模拟业务验证业务代码
System.out.println("用户验证。。。");
}
}
(4)编写XML配置文件,通过代理来实现AOP的前置通知。
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="beforeAdvice" class="com.spring.before.AdviceBeforeComponent"></bean>
<bean id="component" class="com.spring.service.Component"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="com.spring.service.IComponent"></property>
<property name="target" ref="component"></property>
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
</list>
</property>
</bean>
</beans>
配置文件中需要配置org.springframework.aop.framework.ProxyFactoryBean类,这是一个代理工厂的泛型类,可以将任意接口实现代理功能,该类中有三个属性,proxyInterfaces指定所要代理的接口,可以是多个接口,用list配置,这里只指定一个接口Icomponent; target属性表示代理的目标对象,也就是代理类,这里是指com.spring.service.Component;第三个属性interceptorNames指的是拦截器的名称,这里指向的是beforeAdvice,就是前面的com.spring.before.AdviceBeforeComponent类,也可以指定多个前置通知。
(5)编写测试代码
测试代码中,使用ApplicalicationContext获取Bean,ApplicationContext直接读取配置文件来获取Bean,
这里的Bean对象是通过org.springframework.aop.framework.ProxyFactoryBean代理出来的,要转换成相应的接口,也就是代理对象所实现的接口,这里是IComponent,通过这个例子可以看粗Component和AdviceBeforeCompon是两个完全独立的程序,通过ProxyfactoryBean进行代理,从而实现AOP的功能,即通过AOP将一些程序片插入到Component类中,而且Component和AdviceBeforeComponent都是可以重复设计的,彼此之间没有任何耦合。
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.IComponent;
public class TestAdvice {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/spring/before/advice.xml");
IComponent component = (IComponent) context.getBean("proxy");
component.bussiness1();
component.bussiness2();
component.bussiness3();
}
}