Loading... ## 理解: ### **切面:** **公共的**,**通用的**,**重复的功能**称为切面,面向切面编程就是将切面**提取出来**,单独开发,在需要调用的方法中通过动态代理的方式进行注入. ### 理解图: ![](https://www.bdmcom.cn/usr/uploads/2022/08/3469041402.png) ### 文字说明: 实现AOP我们可以分为两部分,一部分为:我们的**具体功能方法**,另一部分为:**公用的,重复的功能方法**,比如事务、日志,我们可能在多个具体功能中都需要这样的功能,这时候我们就可以把这些通用的功能提取出来,这样就形成了切面。通过代理,比如:我们传入某个功能对象(BookServiceImpl)和某个功能的扩展类aop(TransactionalAop)通过两个实现类,就可以实现功能扩展, **静态代理**:只要传入的功能类实现了静态代理中**构造器提供的接口**,就可以随便传。 **动态代理**:只要传入的功能类型实现了静态代理中的**静态方法参数的接口**,就可以随便传,比起静态代理的优势,动态代理的对象方法只要在被代理类中存在,动态代理就可以利用方法名通过反射进行方法调用,而静态代理的对象方法是写死在类里面的,耦合度较高,可扩展性较低。 ### 思路: **面向接口编程:** 属性的类型为接口,形参的类型为接口,方法的返回值为接口。提高程序的可扩展性。 > 我们通过业务接口和切面接口,实现对业务功能的扩展。 ### 业务接口Service 比如有一个Service这样的一个接口,接口中有一个`void buy()` 的方法,有一个BookService实现了Service中的`void buy()` 方法,下面继续 #### service ```java public interface Service { void buy(); } ``` #### BookServiceImpl ```java public class BookServiceImpl implements Service { @Override public void buy() { System.out.println("图书购买功能实现~"); } } ``` ### 切面接口AOP 比如有一个aop这样的接口,接口中有` void before(), void agter(), void exception()` 这三个方法,主要用于在**业务功能前添加功能**,**业务功能后添加功能**,**业务功能出现异常后处理**;如果我们需要使用事务TransactionalAop,我们实现上面的aop接口,在接口中实现具体的功能。 #### aop ```java public interface Aop { default void before(){}; default void after(){}; default void exception(){}; } ``` #### #### TransactionalAop ```java public class TransactionalAop implements Aop { @Override public void before() { System.out.println("事务开启~"); } @Override public void after() { System.out.println("事务提交~"); } @Override public void exception() { System.out.println("事务回滚~"); } } ``` ## 静态代理版: ### 代理对象Agent 传入功能实现类、aop实现类(注意:这两个实现类需要实现构造方法中的接口,多态用法) ```java public class Agent implements Service{ private final Aop aop; private final Service service; public Agent( Service service, Aop aop){ this.aop = aop; this.service = service; } @Override public void buy() { try { // 切面实现 aop.after(); //业务功能 service.buy(); // 切面实现 aop.before(); } catch (Exception e) { e.printStackTrace(); aop.exception(); } } } ``` ### 测试 ```java @Test public void test03() { Service service = new Agent(new BookServiceImpl(), new TransitionAop()); service.buy(); } ``` ![](https://www.bdmcom.cn/usr/uploads/2022/08/41171024.png) ## 动态代理版: ### 代理对象Agent 传入功能实现类、aop实现类(注意:这两个实现类需要实现静态方法中的接口,多态用法) ```java public class ProxyAgent { public static Object getAgent(Service service, Aop aop){ // 返回生成的动态代理对象 return Proxy.newProxyInstance( // 类加载器 service.getClass().getClassLoader(), // 目标对象实现的所有接口 service.getClass().getInterfaces(), // 代理功能实现 new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; try { // 切面 aop.before(); // 业务 obj = method.invoke(service, args); // 切面 aop.after(); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); aop.exception(); } return obj; } } ); } } ``` ### 测试: ```java public class ProxyAgent1 { @Test public void test05(){ // 得到动态代理对象 Service agent = (Service) ProxyAgent.getAgent( new BookServiceImpl(), new TransactionalAop()); agent.buy(); } } ``` ![](https://www.bdmcom.cn/usr/uploads/2022/08/8292076.png) 最后修改:2022 年 08 月 27 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果文章有用,请随意打赏。