第二章动态代理开发
1.动态代理概念
通过代理类为原始类添加额外功能
便于原始类的维护
2.开发环境
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
3.开发步骤
-
创建原始类/目标类
public class UserServiceImpl implements UserService{ public void register(User user) { System.out.println("UserServiceImpl.register()"); } public boolean login(User user) { System.out.println("UserServiceImpl.login()"); return false; } }
-
额外功能
MethodBeforeAdvice
接口public class Before implements MethodBeforeAdvice { // method 原始类中的原始方法 // object 原始方法中的参数 // o 原始对象 public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("---Before.log---"); } }
MethodInterceptor
接口public class Around implements MethodInterceptor { // methodInvocation << 原始方法 public Object invoke(MethodInvocation methodInvocation) throws Throwable { // 运行在原始方法之前 System.out.println("----Around start-----"); Object ret = methodInvocation.proceed(); // 运行在原始方法之后 System.out.println("----Around end-----"); return ret; } }
-
定义切入点
切入点:额外功能加入的位置 目的:程序员自定义给哪个方法加入额外功能
<aop:config> <aop:pointcut id="pc" expression="execution(* *(..))"/> </aop:config>
-
组装
将第二步和第三步整合 切入点 + 额外功能
<aop:config> <aop:advisor advice-ref="before" pointcut-ref="pc"/> </aop:config>
-
调用
目的:获得Spring工厂创建的动态代理对象 注意: 1.Spring工厂通过id属性获得的是代理对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext2.xml"); UserService userService = ctx.getBean("userService", UserService.class); userService.login(new User()); System.out.println(userService.getClass()); // class com.sun.proxy.$Proxy7
4.动态代理细节分析
1.Spring创建的代理类在什么地方
Spring框架在运行时,通过动态字节码技术,在虚拟机内部,程序结束,动态代理类也会小时
小心方法区OutOfMemory
2.动态代理编程简化了代理开发
切入点 + 额外功能
类似于搭积木
3.便于额外功能的维护