笔记之用……
首先有一个接口UserService
package com.spring.test; import org.springframework.stereotype.Component; @Component public interface UserService { public void createUser(); public void deleteUser(); public void updateUser(int id); }
UserDao实现UserService
package com.spring.test; import org.springframework.stereotype.Component; @Component public class UserDao implements UserService { public void createUser() { System.out.println("user saved..."); } public void deleteUser(){ System.out.println("delete user..."); } public void updateUser(int id){ System.out.println("update user..."); } }
想要在这些方法执行的时候加一些业务逻辑,如公共日志或者计算方法执行前后的时间等,将代码以切面的形式切入到方法中,此时可以用动态代理来实现,
aop的动态代理底层是用jdk的动态代理实现的proxy和InvocationHandler,需实现java.lang.reflect.InvocationHandler
首先定义一个LogInteceptor来实现InvocationHandler:
package com.spring.log; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Calendar; import java.util.Date; /***************** * 日志类 * * @author Administrator * */ public class LogInteceptor implements InvocationHandler{ private Object target;//被代理的对象 public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforeMethod(method);//在方法执行前所要执行的业务逻辑 long starttime=System.currentTimeMillis(); method.invoke(target, args); long result=System.currentTimeMillis()-starttime; System.out.println("执行时间为:"+result+"毫秒"); afterMethod(method);//在方法执行后所要执行的业务逻辑 return null; } public void beforeMethod(Method m){ System.out.println(m.getName()+"执行before...."); } public void afterMethod(Method m){ System.out.println(m.getName()+"执行after..."); } }
然后用JUnit来进行测试
package com.junit.test; import java.lang.reflect.Proxy; import com.spring.log.LogInteceptor; import com.spring.test.UserDao; import com.spring.test.UserService; public class Test { @org.junit.Test public void testProxy(){ UserDao userDao=new UserDao();//被代理的对象 LogInteceptor logInteceptor=new LogInteceptor();//获取日志的InvocationHandler logInteceptor.setTarget(userDao);//把被代理的对象设为userDao //设置代理对象,参数1:被代理对象的classloader,参数2:被代理对象所实现的接口(该对象必须要实现接口,不然无法产生代理),参数3:指定处理的InvocationHandler UserService userService=(UserService)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), new Class[]{UserService.class}, logInteceptor); userService.createUser();//执行方法 userService.deleteUser();//执行方法 userService.updateUser(1001);//执行方法 } }
执行结果:
createUser执行before....
user saved...
---执行时间为:0毫秒
createUser执行after...
deleteUser执行before....
delete user...
---执行时间为:0毫秒
deleteUser执行after...
updateUser执行before....
update user...
---执行时间为:0毫秒
updateUser执行after...
接下来来点实际的..........................
定义一个LogInterceptor,让dao里的方法在执行的前后执行某些特定的方法
package com.spring.log; public class LogInterceptor { public void beforeMethod(){ System.out.println("方法执行前执行"); } public void afterMethod(){ System.out.println("方法执行后执行"); } }
定义的beforeMethod和afterMethod在applicationContext.xml里用aop配置
<bean id="mylog" class="com.spring.log.LogInterceptor"></bean> <aop:config> <aop:aspect id="log" ref="mylog"> <aop:pointcut expression="execution (* com.spring.test.*.*(..))" id="point" /><!--切入点--> <aop:before method="beforeMethod" pointcut-ref="point"/><!-- 定义方法before前执行自己定义的beforeMethod --> <aop:after method="afterMethod" pointcut-ref="point"/><!-- 定义方法after后执行自己定义的afterMethod --> </aop:aspect> </aop:config>
当然还可以配置
<aop:around method=""/> <aop:after-returning method=""/> <aop:after-throwing method=""/>
最后用JUnit测试:
@org.junit.Test public void Test(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService service = (UserService) ctx.getBean("userDao"); service.createUser(); }
执行结果:
方法执行前执行
user saved...
方法执行后执行
如果要获取执行的类和方法,可以接一个JoinPoint参数,用来获取执行的方法名
package com.spring.log; import org.aspectj.lang.JoinPoint; public class LogInterceptor { public void beforeMethod(JoinPoint point){ System.out.println("方法执行前执行"); //System.out.println(point.getTarget());//获取类com.spring.test.UserDao@15e0873 //System.out.println(point.getSignature().getName());//获取方法名 System.out.println(point.getTarget()+"类的"+point.getSignature().getName()+"方法执行!!!"); } public void afterMethod(JoinPoint point){ System.out.println("方法执行后执行"); System.out.println(point.getTarget()+"类的"+point.getSignature().getName()+"方法执行完毕!!!"); } }
相关推荐
spring之AOP(动态代理),包括jdk动态代理和CGLib动态代理
Spring-AOP-利用java中的动态代理和Spring的拦截器做到AOP
主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。主要包括:1. AOP的常见概念 2. 静态代理 3. jdk动态代理 4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB ...
Jdk动态代理,基于接口的代理示例 InovactionHandler Proxy
基于JDK的动态代理。必须是面向接口的,只有实现了具体接口的类才能生成代理对象
Spring AOP 使用的动态代理主要有两种方式:JDK 动态代理和 CGLIB 代理。 JDK 动态代理:用于代理实现了接口的类。Spring 会使用 java.lang.reflect.Proxy 类来创建代理对象。 CGLIB 代理:用于代理没有实现接口的...
AOP的意思就是面向切面编程。本文主要是通过梳理JDK中自带的反射机制,实现 AOP动态代理模式,这也是Spring AOP 的实现原理
aspectj-1.7.4.jar,aspectjweaver-1.7.4.jar
AOP之JDK动态代理和CGLib动态代理 ,具体效果和过程看博文 http://blog.csdn.net/evankaka/article/details/45195383
spring aop jdk 动态代理的底层实现解析模拟
Spring框架的AOP中重要的一个知识点,动态代理,springAOP框架会根绝实际情况选择使用jdk的动态代理还是cglib的动态代理
死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序
springAOP配置实现动态代理,有利于熟悉动态代理原理,深入了解spring。
我们还提供了实际示例,演示如何在Spring AOP中使用JDK动态代理。 CGLib动态代理: 我们将深入研究CGLib动态代理,它允许您在不需要接口的情况下创建代理对象。您将了解CGLib的工作原理,以及如何生成子类来实现...
通过动态代理模拟Spring AOP,通过动态代理模拟Spring AOP
spring aop jar 包
spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting ...Spring AOP 代理是什么? 引介(Introduction)是什么? 连接点(Joint Point)和切入点(Point Cut)是什么? 织入(Weaving)是什么?
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
SpringAOP之探秘(动态代理、责任链模式、注解使用)- 详情:https://blog.csdn.net/Dream_Weave/article/details/85008674