模拟AOP框架实现-2

87 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

3.4 代码实现版本四

public interface AOP {\
    default void before(){}\
    default void after(){}\
    default void exception(){}\
}

public class TransAop implements AOP {\
    @Override\
    public void before() {\
        System.*out*.println("事务开启............");\
    }\
    @Override\
    public void after() {\
        System.*out*.println("事务提交...........");\
    }\
    @Override\
    public void exception() {\
        System.*out*.println("事务回滚...........");\
    }\
}

public class LogAop implements AOP {\
    @Override\
    public void before() {\
        System.*out*.println("前置日志输出 .............");\
    }\
}

public class Agent  implements Service{\
    public Service target;//为了灵活的切换业务,上接口\
    public AOP aop;  //为了灵活的切换切面 ,上接口\
    public Agent(Service target,AOP aop){\
        this.target = target;\
        this.aop = aop;\
    }\
    @Override\
    public void buy() {\
        try {\
            //切面功能\
            aop.before();//哪个实现类来了,调用哪个实现类的功能\
            //业务功能\
            target.buy();\
            //切面功能\
            aop.after();\
        } catch (Exception e) {\
            aop.exception();\
        }\
    }\
}

public class MyTest04 {\
    @Test\
    public void test03(){\
        Service agent = new Agent(new ProductServiceImpl(),new LogAop());\
        agent.buy();\
    }\
}

3.5 代码实现版本五

完全的解耦了业务与服务性质的业务(切面),切换功能和方面更灵活。但是只能是buy()一个功能,如果再代理的功能多了,就不行了,解决方案是动态代理模式。

public class ProxyFactory {\
    //通过方法参数传入目标对象和切面对象\
    public static Object getAgent(Service target,AOP aop){\
        return Proxy.*newProxyInstance*(target.getClass().getClassLoader(),\
                target.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(target,args);  //灵活的进行业务功能切换\
                            aop.after();  //灵活的进行切面功能切换\
                        } catch (Exception e) {\
                            aop.exception();  //灵活的进行切面功能切换\
                        }\
                        return obj;//目标方法的返回值\
                    }\
                }); //返回动态代理对象\
    }\
}

public class MyTest05 {\
    @Test\
    public void test03(){\
       //得到代理对象\
        Service agent = (Service) ProxyFactory.*getAgent*(new ProductServiceImpl(),new TransAop());\
        Service agent1 = (Service) ProxyFactory.*getAgent*(agent,new LogAop());\
        agent1.buy();\
    }\
}

运行结果 :

image.png

这个解决方案很好的解决了业务和切面的紧耦合。可以灵活的进行业务的切换,可以灵活的进行切面的切换。可以嵌套切面的处理。