Spring5深入浅出篇:Spring中静态代理与动态代理
很多粉丝私信我这个Spring5的课程在哪看,这边是在B站免费观看欢迎大家投币支持一下.
静态代理设计模式
- 在JavaEE分层开发开发中,那个层次对于我们来讲最重要
DAO ---> Service --> Controller JavaEE分层开发中,最为重要的是Service层
- Service层中包含了哪些代码?
Service层中 = 核⼼功能(⼏⼗⾏ 上百代码) + 额外功能(附加功能) 1. 核⼼功能 业务运算 DAO调⽤ 2. 额外功能 1. 不属于业务 2. 可有可⽆ 3. 代码量很⼩ 事务、⽇志、性能...
- 额外功能书写在Service层中好不好?
Service层的调⽤者的⻆度(Controller):需要在Service层书写额外功能。 软件设计者:Service层不需要额外功能
代理设计模式
概念
通过代理类,为原始类(⽬标)增加额外的功能 好处:利于原始类(⽬标)的维护
名词解释
1. ⽬标类 原始类 指的是 业务类 (核⼼功能 --> 业务运算 DAO调⽤) 2. ⽬标⽅法,原始⽅法 ⽬标类(原始类)中的⽅法 就是⽬标⽅法(原始⽅法) 3. 额外功能 (附加功能) ⽇志,事务,性能
代理开发的核⼼要素
代理类 = ⽬标类(原始类) + 额外功能 + 原始类(⽬标类)实现相同的接⼝ 房东 ---> public interface UserService{ m1 m2 } UserServiceImpl implements UserService{ m1 ---> 业务运算 DAO调⽤ m2 } UserServiceProxy implements UserService m1 m2
编码
静态代理:为每⼀个原始类,⼿⼯编写⼀个代理类 (.java .class)
静态代理存在的问题
1. 静态类⽂件数量过多,不利于项⽬管理 UserServiceImpl UserServiceProxy OrderServiceImpl OrderServiceProxy 2. 额外功能维护性差 代理类中 额外功能修改复杂(麻烦)
Spring的动态代理开发
Spring动态代理的概念
概念:通过代理类为原始类(⽬标类)增加额外功能 好处:利于原始类(⽬标类)的维护
搭建开发环境
<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>
Spring动态代理的开发步骤
创建原始对象(⽬标对象)
public class UserServiceImpl implements UserService { @Override public void register(User user) { System.out.println("UserServiceImpl.register 业务运算 + DAO "); } @Override public boolean login(String name, String password) { System.out.println("UserServiceImpl.login"); return true; } }
<bean id="userService" class="com.baizhiedu.proxy.UserServiceImpl"/>
额外功能 MethodBeforeAdvice接⼝
额外的功能书写在接⼝的实现中,运⾏在原始⽅法执⾏之前运⾏额外功能。
public class Before implements MethodBeforeAdvice { /* 作⽤:需要把运⾏在原始⽅法执⾏之前运⾏的额外功能,书写在before⽅法中 */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("-----method before advice log------ "); } }
<bean id="before" class="com.baizhiedu.dynamic.Before"/>
定义切⼊点
切⼊点:额外功能加⼊的位置 ⽬的:由程序员根据⾃⼰的需要,决定额外功能加⼊给那个原始⽅法 register login 简单的测试:所有⽅法都做为切⼊点,都加⼊额外的功能。
<aop:config> <aop:pointcut id="pc" expression="execution(* *(..))"/> </aop:config> 表达的含义:所有的⽅法 都加⼊ before的额外功能 <aop:advisor advice-ref="before" pointcut-ref="pc"/>
调⽤
⽬的:获得Spring⼯⼚创建的动态代理对象,并进⾏调⽤ ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); 注意: 1. Spring的⼯⼚通过原始对象的id值获得的是代理对象 2. 获得代理对象后,可以通过声明接⼝类型,进⾏对象的存储 UserService userService= (UserService)ctx.getBean("userService"); userService.login("") userService.register()
动态代理细节分析
Spring创建的动态代理类在哪⾥?
Spring框架在运⾏时,通过动态字节码技术,在JVM创建的,运⾏在JVM内部,等程序结束后,会和JVM⼀起消失 什么叫动态字节码技术:通过第三个动态字节码框架,在JVM中创建对应类的字节码,进⽽创建对象,当虚拟机结束,动态字节码跟着消失。 结论:动态代理不需要定义类⽂件,都是JVM运⾏过程中动态创建的,所以不会造成静态 代理,类⽂件数量过多,影响项⽬管理的问题。
动态代理编程简化代理的开发
在额外功能不改变的前提下,创建其他⽬标类(原始类)的代理对象时,只需要指 定原始(⽬标)对象即可。
动态代理额外功能的维护性⼤⼤增强
以上便是本文的全部内容,我是全干程序员demo,每天为你带来最新好用的开发运维工具,如果你觉得用,请点赞,让更多的人了解相关工具
如果你想了解更多关于全干程序员demo,还有更多付费工具免费破解,可以关注公众号-全干程序员demo,后面文章会首先同步至公众号