
aop( Aspect-Oriented Programming)前置通知原理案例讲解
编程步骤;
- 定义接口
- 编写对象(被代理的对象即目标对象)
- 编写通知(前置通知即目标方法调用前调用)
- 在beans.xml文件中配置
4.1. 配置 被代理对象即目标对象
4.2. 配置通知
4.3. 配置代理对象 其是ProxyFactoryBean的对象实例
4.3.1 配置代理接口集
4.3.2 织入通知
4.3.3 配置被代理对象
直接上代码
1.分别创建两个接口如下:
TestServiceInterface.java接口
package com.LHB.aop; public interface TestServiceInterface { public void sayHello();
}
TestServiceInterface2.java接口
package com.LHB.aop; public interface TestServiceInterface2 { public void sayBye();
}
2. 创建被代理对象(目标对象)类testService.java,该类实现了TestServiceInterface和TestServiceInterface2两个接口方法
package com.LHB.aop; public class testService implements TestServiceInterface,TestServiceInterface2 { private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void sayHello() {
// TODO Auto-generated method stub System.out.println("hello " + name);
}
@Override
public void sayBye() {
// TODO Auto-generated method stub
System.out.println("Bye "+ name);
} }
3. 编写前置通知即MyMethodBeforeAdvice.java,该类实现了MethodBeforeAdvice接口中的before(method method,Object[] args,Object target )方法。
注意:在实现该接口的时候需要导入spring-aop-5.0.1.RELEASE.jar包(本案例在spring5.0.1版本下实现的)
package com.LHB.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class MyMethodBeforeAdvice implements MethodBeforeAdvice { /**
* 功能:该函数将在目标函数执行前首先执行
* method:被调用方法名字
* args:给method传递的参数
* target:被代理的目标对象
*/
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
// TODO Auto-generated method stub
//method.getName()方法将得到目标函数的函数名称
System.out.println("记录日志...." + method.getName());
} }
4.通过new/File新建一个bean.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!--4.1 配置一个被代理的对象即目标对象-->
<bean id="testService" class="com.LHB.aop.testService">
<property name="name" value="张三" />
</bean>
<!--4.2 配置前置通知 -->
<bean id="MyMethodBeforeAdvice" class="com.LHB.aop.MyMethodBeforeAdvice" />
<!--4.3 配置代理对象 -->
<bean id="ProxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--4.3.1 配置代理接口集 -->
<property name="proxyInterfaces">
<list>
<value>com.LHB.aop.TestServiceInterface</value>
<value>com.LHB.aop.TestServiceInterface2</value>
</list>
</property>
<!--4.3.2 把通知织入到代理对象 -->
<property name="interceptorNames">
<!-- 相当于把MyMethodBeforeAdvice前置通知把代理对象关联起来,也可以把通知看成拦截器 -->
<value>MyMethodBeforeAdvice</value>
</property>
<!--4.3.3 配置被代理对象可以指定 -->
<property name="target" ref="testService"/> </bean> </beans>
5. 创建一个测试类APP
package com.LHB.aop; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ac = new ClassPathXmlApplicationContext("com/LHB/aop/beans.xml");
TestServiceInterface tsi = (TestServiceInterface) ac.getBean("ProxyFactoryBean");
tsi.sayHello();
((TestServiceInterface2)tsi).sayBye(); } }
6. 运行结果