Spring AOP 创建增强类
AOP联盟为增强定义了org.aopalliance.aop.Advice接口,Spring支持5种类型的增强:
package com.yyq.advice;
public interface Waiter {
void greetTo(String name);
void serveTo(String name);
}
NaiveWaiter服务类:
package com.yyq.advice;
public class NaiveWaiter implements Waiter {
@Override
public void greetTo(String name) {
System.out.println("greet to " + name + "...");
}
@Override
public void serveTo(String name) {
System.out.println("serving to " + name + "...");
}
}
前置增强实现类:
package com.yyq.advice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class GreetingBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
String clientName = (String) objects[0];
System.out.println("How are you ! Mr." + clientName + ".");
}
}
测试方法:
@Test
public void testBeforeAdvice(){
Waiter target = new NaiveWaiter();
BeforeAdvice advice = new GreetingBeforeAdvice();
ProxyFactory pf = new ProxyFactory(); //Spring提供的代理工厂
pf.setTarget(target); //设置代理目标
pf.addAdvice(advice);
Waiter proxy = (Waiter)pf.getProxy(); //生成代理实例
proxy.greetTo("John");
proxy.serveTo("Tom");
}
<bean id="greetingAdvice" class="com.yyq.advice.GreetingBeforeAdvice"/>
<bean id="target" class="com.yyq.advice.NaiveWaiter"/> <bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.yyq.advice.Waiter"
p:interceptorNames="greetingAdvice"
p:target-ref="target"/>
ProxyFactoryBean 是FactoryBean接口的实现类。
@Test
public void testBeforeAdvice2(){
String configPath = "com\\yyq\\advice\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter1");
waiter.greetTo("Joe");
}
package com.yyq.advice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class GreetingAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o2) throws Throwable {
System.out.println("Please enjoy yourself.");
}
}
在beans.xml文件添加后置增强:
<bean id="greetingBefore" class="com.yyq.advice.GreetingBeforeAdvice"/>
<bean id="greetingAfter" class="com.yyq.advice.GreetingAfterAdvice"/>
<bean id="waiter2" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.yyq.advice.Waiter"
p:interceptorNames="greetingBefore,greetingAfter"
p:target-ref="target"/>
测试方法:
@Test
public void testBeforeAndAfterAdvice(){
String configPath = "com\\yyq\\advice\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter2");
waiter.greetTo("Joe");
}
package com.yyq.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class GreetingInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object[] args = methodInvocation.getArguments();
String clientName = (String) args[0];
System.out.println("Hi,Mr " + clientName + ".");
Object obj = methodInvocation.proceed();
System.out.println("Please enjoy yourself~");
return obj;
}
}
Spring 直接使用AOP联盟所定义的MethodInterceptor作为环绕增强的接口。该接口拥有唯一的接口方法 Object invoke(MethodInvocation invocation), MethodInvocation不但封装目标方法及其入参数组,还封装了目标方法所在的实例对象,通过MethodInvocation的getArguments()可以获取目标方法的入参数组,通过proceed()反射调用目标实例相应的方法。
<bean id="greetingAround" class="com.yyq.advice.GreetingInterceptor"/>
<bean id="waiter3" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.yyq.advice.Waiter"
p:interceptorNames="greetingAround"
p:target-ref="target"/>
测试方法:
@Test
public void testAroundAdvice(){
String configPath = "com\\yyq\\advice\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter3");
waiter.greetTo("Joe");
}
package com.yyq.advice;
public class Forum {
private int forumId;
public int getForumId() {
return forumId;
}
public void setForumId(int forumId) {
this.forumId = forumId;
}
}
ForumService业务类:
package com.yyq.advice;
import java.sql.SQLException;
public class ForumService {
public void removeForum(int forumId){
System.out.println("removeForum....");
throw new RuntimeException("运行异常");
}
public void updateForum(Forum forum)throws Exception{
System.out.println("updateForum");
throw new SQLException("数据更新操作异常。");
}
}
TransactionManager异常抛出增强实现类:
package com.yyq.advice;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
public class TransactionManager implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
System.out.println("----------------");
System.out.println("method:" + method.getName());
System.out.println("抛出异常:" + ex.getMessage());
System.out.println("成功回滚事务。");
}
}
<bean id="transactionManager" class="com.yyq.advice.TransactionManager"/>
<bean id="forumServiceTarget" class="com.yyq.advice.ForumService"/>
<bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="transactionManager"
p:target-ref="forumServiceTarget"
p:proxyTargetClass="true"/>
测试方法:
@Test
public void testThrowsAdvice(){
String configPath = "com\\yyq\\advice\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
ForumService fs = (ForumService)ctx.getBean("forumService");
try{
fs.removeForum(10);
} catch (Exception e) {}
try{
fs.updateForum(new Forum());
} catch (Exception e) {}
}
package com.yyq.advice;
public interface Monitorable {
void setMonitorActive(boolean active);
}
ControllablePerformanceMonitor 为引介增强实现类:
package com.yyq.advice;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
public class ControllablePerformanceMonitor extends DelegatingIntroductionInterceptor implements Monitorable {
private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>();
@Override
public void setMonitorActive(boolean active) {
MonitorStatusMap.set(active);
}
public Object invoke(MethodInvocation mi) throws Throwable {
Object obj = null;
if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) {
PerformanceMonitor.begin(mi.getClass().getName() + "." + mi.getMethod().getName());
obj = super.invoke(mi);
PerformanceMonitor.end();
} else {
obj = super.invoke(mi);
}
return obj;
}
}
PerformanceMonitor监视类:
package com.yyq.advice; public class PerformanceMonitor {
private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>();
public static void begin(String method) {
System.out.println("begin monitor...");
MethodPerformance mp = new MethodPerformance(method);
performanceRecord.set(mp);
}
public static void end(){
System.out.println("end monitor...");
MethodPerformance mp = performanceRecord.get();
mp.printPerformance();
}
}
MethodPerformance记录性能信息:
public class MethodPerformance {
private long begin;
private long end;
private String serviceMethod;
public MethodPerformance(String serviceMethod){
this.serviceMethod = serviceMethod;
this.begin = System.currentTimeMillis();
}
public void printPerformance(){
end = System.currentTimeMillis();
long elapse = end - begin;
System.out.println(serviceMethod + "花费" + elapse + "毫秒。");
}
}
在beans.xml文件添加引介增强:
<bean id="pmonitor" class="com.yyq.advice.ControllablePerformanceMonitor"/>
<bean id="forumServiceImplTarget" class="com.yyq.advice.ForumServiceImpl"/>
<bean id="forumService2" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interfaces="com.yyq.advice.Monitorable"
p:interceptorNames="pmonitor"
p:target-ref="forumServiceImplTarget"
p:proxyTargetClass="true"/>
@Test
public void testIntroduce(){
String configPath = "com\\yyq\\advice\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
ForumServiceImpl forumServiceImpl = (ForumServiceImpl)ctx.getBean("forumService2");
forumServiceImpl.removeForum(23);
forumServiceImpl.removeTopic(1023);
Monitorable monitorable = (Monitorable)forumServiceImpl;
monitorable.setMonitorActive(true);
forumServiceImpl.removeForum(22);
forumServiceImpl.removeTopic(1023);
}
Spring AOP 创建增强类的更多相关文章
- (spring-第17回【AOP基础篇】) 创建增强类
一. 增强类包含的信息: a) 横切逻辑(插入的具体代码) b) 部分连接点信息(在方法的哪个位置插入代码,比如方法前.方法后等). 二. 增强的类型 每一种增强有一个需要实现的增强类 ...
- Spring aop:decare-parent 为类增加新的方法
Spring aop:decare-parent 为类增加新的方法: 使用XML配置的方式: XML: <?xml version="1.0" encoding=" ...
- Spring AOP切面变成——创建增强类
说明 Spring使用增强类定义横向逻辑,同时Spring只支持方法连接点,增量类还包含在方法的哪一点添加横切代码的方位信息.所以增强既包含横向逻辑,又包含部分连接点的信息. 类型 按着增强在目标类方 ...
- Spring aop——前置增强和后置增强 使用注解Aspect和非侵入式配置
AspectJ是一个面向切面的框架,它扩展了java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节码字节编码规范的Class文件 确保使用jdk为5.0以 ...
- 阿里四面:你知道Spring AOP创建Proxy的过程吗?
Spring在程序运行期,就能帮助我们把切面中的代码织入Bean的方法内,让开发者能无感知地在容器对象方法前后随心添加相应处理逻辑,所以AOP其实就是个代理模式. 但凡是代理,由于代码不可直接阅读,也 ...
- spring aop无法拦截类内部的方法调用
1.概念 拦截器的实现原理就是动态代理,实现AOP机制.Spring 的代理实现有两种:一是基于 JDK Dynamic Proxy 技术而实现的:二是基于 CGLIB 技术而实现的.如果目标对象实现 ...
- Spring AOP 创建切面
增强被织入到目标类的所有方法中,但是如果需要有选择性的织入到目标类某些特定的方法中时,就需要使用切点进行目标连接点的定位.增强提供了连接点方位信息:如织入到方法前面.后面等,而切点进一步描述织 ...
- Spring AOP(基于代理类的AOP实现)
#基于代理类的AOP实现:step1: 1 package com.sjl.factorybean; /**切面类*/ import org.aopalliance.intercept.MethodI ...
- Spring AOP创建Throwdvice实例
1.异常发生的时候,通知某个服务对象做处理 2.实现throwsAdvice接口 接口实现: public interface IHello { public void sayHello(String ...
随机推荐
- C#新语法特性前瞻
今天逛微软的UserVoice site发现了几个有很有用,也很可能被添加到新版C#中的语法,当然也可能被推迟到下一版,拿出来给大家分享一下. 另外还没投票的可以去为自己最想要的新特性投票,有兴趣的可 ...
- Dijkstra算法亲自实践
按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的集合(初始时只含有源点V0) (2)V-S=T:尚未确定的顶点集合 将T中顶点按递增的次序加入到S中,保证: (1)从源点 ...
- 浅析Java反射机制
目前,在项目中使用Java反射机制(除Spring框架)的地方不多,但为后续准备,简单将最近的反射体会总结如下: 1. 按光学中的反射,可以将java中的反射理解为“镜像”.有以下用途: Java反射 ...
- Leetcode#123 Best Time to Buy and Sell Stock III
原题地址 最直观的想法就是划分成两个子问题,每个子问题变成了:求在某个范围内交易一次的最大利润 在只能交易一次的情况下,如何求一段时间内的最大利润?其实就是找股价最低的一天买进,然后在股价最高的一天卖 ...
- mongodb维护常用命令
一,用户操作:1. #进入数据库adminuse admin2. #增加或修改用户密码db.addUser('name','pwd')3. #查看用户列表db.system.users.find()4 ...
- ios7.1 在线安装 失败的解决办法
昨天升级7.1之后,证书制作的app就无法在线安装了,各种搜..说需要https.搭web服务器,起https服务,结果不行.终于明白,https需要权威认证,自己搭建的不行,需要买第三方权威机构的认 ...
- Sqli-labs less 59
Less-59 与less58一致,直接给出一个示例payload: http://127.0.0.1/sqli-labs/Less-59/?id=-1 union select extractval ...
- vi/vim使用指北 ---- Introducting the ex Editor
本章介绍ex编辑器,为什么要介绍这样一个新的编辑器呢:其实ex编辑器不能算是一个新的编辑器,vi只是它的visual model,它已经是一个更普遍,基于行的编辑器.ex提供更大机动和范围的编辑命令. ...
- 11gR2数据库日志报错:Fatal NI connect error 12170、
11gR2数据库日志报错:Fatal NI connect error 12170.TNS-12535.TNS-00505 [问题点数:100分,结帖人MarkIII] 不显示 ...
- 几种CPU架构
原文链接:http://blog.csdn.net/wyzxg/article/details/5027738 这几天在下载RPM包的时候,总会看见x86,x86-64,IA64,i386,i586等 ...