java架构解密——深入再造AOP

在上篇博客中,大家和我一起研究了AOP的基本实现,但是,也给大家遗留了很多问题,在这篇博客,咱们一起研究如何针对这些问题进行持续的优化,看看在咱们的手里,AOP会成长为一个什么样的东西!

回顾:

看看上篇博客中,咱们一起实现的AOP类图:

咱们看看在CGLIB类里的问题

<span style="font-size:18px;">public class CGLibDynamicProxy implements MethodInterceptor {  

    private static CGLibDynamicProxy instance = new CGLibDynamicProxy();  

    private CGLibDynamicProxy() {
    }  

    public static CGLibDynamicProxy getInstance() {
        return instance;
    }  

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls) {
        return (T) Enhancer.create(cls, this);
    }  

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        before();
        Object result = proxy.invokeSuper(target, args);
        after();
        return result;
    }  

<span style="color:#ff6600;">    private void before() {
        System.out.println("Before");
    }  

    private void after() {
        System.out.println("After");
    }  </span>

}</span>

1,扩展服务

这样我们的扩展就会变得困难,大家试想一下这个场景,我们写好的业务,需要增加一个功能,就要写一个代理类,功能的变化,也必须修改代码,这就给我们的代码维护带来了很大的负担!如果我们要第一次要扩展2个方法,写了代理,下一次扩展3个,写了代理,下一次扩展1个写了代理,下一次不想要第一次的第2个方法了,怎么办?的确,这样的维护,是我们不想看到的,所以,我们将扩展的公共服务放到了一个容器中,大家看类图:

1.1封装公共服务类:

<span style="font-size:18px;">public class ProxyMehds  {
	//盛放方法执行前的对象的容器
	private  HashMap<String,Object> beforBeans;
    private  HashMap<String,Object> afterBeans;

    //配制方法执行前要执行哪些方法
	private  HashMap<String,String> beforMethods;
    private  HashMap<String,String> afterMethods;

    @Override
    public void beforeBean()  {  

    	try{

	    	for (HashMap.Entry<String, Object> entry : beforBeans.entrySet()) {

	    	    String objectKey = entry.getKey();
	    	    Object objectValure = entry.getValue();
	    	    Method beforMehod = objectValure.getClass().getMethod(beforMethods.get(objectKey));
	    	    beforMehod.invoke(objectValure);

	    	}

    	}catch(Exception ex){
    		ex.printStackTrace();
    	}
    	//Method sAge = c.getMethod("setAge");
    }  

    @Override
    public void afterBean() {  

    	try{

	    	for (HashMap.Entry<String, Object> entry : afterBeans.entrySet()) {

	    	    String objectKey = entry.getKey();
	    	    Object objectValure = entry.getValue();
	    	    Method beforMehod = objectValure.getClass().getMethod(afterMethods.get(objectKey));
	    	    beforMehod.invoke(objectValure);

	    	}

    	}catch(Exception ex){
    		ex.printStackTrace();
    	}

    }

	public HashMap<String, Object> getBeforBeans() {
		return beforBeans;
	}

	public void setBeforBeans(HashMap<String, Object> beforBeans) {
		this.beforBeans = beforBeans;
	}

	public HashMap<String, Object> getAfterBeans() {
		return afterBeans;
	}

	public void setAfterBeans(HashMap<String, Object> afterBeans) {
		this.afterBeans = afterBeans;
	}

	public HashMap<String, String> getBeforMethods() {
		return beforMethods;
	}

	public void setBeforMethods(HashMap<String, String> beforMethods) {
		this.beforMethods = beforMethods;
	}

	public HashMap<String, String> getAfterMethods() {
		return afterMethods;
	}

	public void setAfterMethods(HashMap<String, String> afterMethods) {
		this.afterMethods = afterMethods;
	}

}</span>

1.2封装代理类:

<span style="font-size:18px;">public class CGLibDynamicProxy implements MethodInterceptor {  

    private static CGLibDynamicProxy instance = new CGLibDynamicProxy();  

    private ProxyMehds proxyMehds;

    private CGLibDynamicProxy() {
    }  

    public static CGLibDynamicProxy getInstance() {
        return instance;
    }  

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls) {
        return (T) Enhancer.create(cls, this);
    }  

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    	proxyMehds.beforeBean();
        Object result = proxy.invokeSuper(target, args);
        proxyMehds.afterBean();
        System.out.println("");

        return result;
    }

	public ProxyMehds getProxyMehds() {
		return proxyMehds;
	}

	public void setProxyMehds(ProxyMehds proxyMehds) {
		this.proxyMehds = proxyMehds;
	}  

}</span>

1.3服务类:

<span style="font-size:18px;">public class AspectClass1 {
	public void SayHello(){
		System.out.println("This is AspectClass1.SayHello!");
	}
}</span>

1.4客户端:

<span style="font-size:18px;">public class Client {
	public static void main(String[] args) { 

		HashMap<String,Object> beforBeans;
	    HashMap<String,Object> afterBeans;

		HashMap<String,String> beforMethods;
	    HashMap<String,String> afterMethods;

	    beforMethods=new HashMap();
    	beforBeans=new HashMap();
    	beforBeans.put("AspectClass1", new AspectClass1());

    	beforMethods.put("AspectClass1", "SayHello");
    	beforMethods.put("AspectClass2", "SayGoodBye");

    	afterMethods=new HashMap();
    	afterBeans=new HashMap();
    	afterBeans.put("AspectClass3", new AspectClass3());
    	afterBeans.put("AspectClass4", new AspectClass4());
    	afterMethods.put("AspectClass3", "SayHi");
    	afterMethods.put("AspectClass4", "Eat");

    	ProxyMehds proxyMehds =new ProxyMehds();
    	proxyMehds.setBeforBeans(beforBeans);
    	proxyMehds.setBeforMethods(beforMethods);
    	proxyMehds.setAfterBeans(afterBeans);
    	proxyMehds.setAfterMethods(afterMethods);

		//实例代理类
        CGLibDynamicProxy cglib =CGLibDynamicProxy.getInstance();

        //接受切面
        cglib.setProxyMehds(proxyMehds);

        //接受要代理的对象
        Greeting greeting = cglib.getProxy(GreetingImpl.class);

        //执行对象的某个方法
        greeting.sayHello("Jack");
    }
}</span>

总结:

这样封装之后的好处是什么呢,就是我们的服务不再固定,而是在代理中定义了一个空壳子,这样每次使用,都是复用的空壳子,也是我们常说的框架,而后期的服务类是后加入的,在客户端动态初始化制定的,这样我们的扩展就变得方便,写好一个类,我们就可以直接配置下xml(类似于客户端的组装)就可以实现这样的功能!让功能的扩充变得简单!

在代码的实现上,功能实现是编写代码的第一步,而我们的大多程序员都做到了第一步,想要获得更高的薪水,就要有些和其他人不一样的东西,那么,这时候,业务来理解水平,抽象能力,实现能力,优化能力,逐渐在以后的晋升中起到至关重要的作用,而这些能力有一个公共的父类,就是全局观,在全局上考虑问题,包含时间与空间两个方向,当时间长了,变化怎么办?人数多了,数据量大了怎么办?

成为一个优秀的架构人员,我们要学习的还有很多!

时间: 2024-11-01 17:29:27

java架构解密——深入再造AOP的相关文章

java架构解密——AOP之动态代理实现

在上篇博客中,我们在宏观上介绍了AOP的底层实现,具体见博客java架构解密--Spring框架的AOP,在博客中,我们讲述了Aop的一些设计上的思路,今天,咱们就具体的实现,和大家一起探讨,看看AOP是怎么一步一步走到今天,而且有些图,也要做些纠正! 一,代码演变 前提:最初要实现的功能(打招呼) 代码: 接口: <span style="font-size:18px;">public interface Greeting { void sayHello(String n

java架构解密——Spring框架的AOP

一直以来,我们应用了不少的AOP框架,但是对于AOP的底层实现却没有过多的深入,古话就是"知其然,不知其所以然",随着AOP学术讨论的骤然兴起,我也开拓了自己的眼界,深入了解了AOP这个五彩斑斓的世界! 先来看看大众的定义: 百度百科: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函

java架构解密——双容器优化aop

上篇博客中,提出,优化是个无止境的过程,的确,随着需求的变化,软硬件基础的升级,我们越来越不考虑代码的容量,而是考虑代码的质量,但是随着研究的深入,到了某个阶段,我们也要考虑代码的容量问题,这时,容器的概念,脱颖而出,在上篇博客将服务类作为一个接口传入,实际在后台是一个map容器,我们不仅包含了map的全部实现,还实现了服务类的叠加,但是美中不足的是,我们的业务类,还是单个的对象,就如下图: 类图改造 这时,我们如果想为更多的业务提供服务,就必须编写更多的aop,这不符合我们的原则,基于这一点,

java架构解密——用接口改造AOP

优化是个无止境的工作,在AOP的路上,我们走得很远,但是还有很多的工作,我们没有做,比如,将aop的业务部分封装成容器,将aop的服务部分改造成面向接口的,这样就不受具体的形式上的限制了!这样AOP的优化,就又前进了一步,也是符合咱们的面向接口编程的思想,下面就和我一起研究下如何将接口的思想融入到aop的实现中. 回顾: 在上篇博客中,我们将aop的服务封装到了容器中: 这样的好处就是我们可以使用配置文件扩展服务类,服务类不再受限于具体的形式与方法,而我们封装的服务类和动态代理,构成了这样的一个

java架构解密——实时动态aop

在上篇博客中个,咱们一起组建了一个容器,里面封装了业务,这样,咱们就将业务和服务的组装放到了客户端,而客户端就相当于咱们的开发中使用到的配置文件,大家发现问题了吗?就是我不能动态改动了?业务容器在代理完成后,重新添加一个容器,这时候,是不被允许的,那这个容器就是个编译时起作用的容器,他就丧失了很多的灵活性! 那怎么办呢?实际就是调换一下调用顺序就好,大家看看结果: 1,类图对比 改造后类图 2,代码实现: 2.1代理类的变化: /** * 打招呼动态代理类,给业务类添加功能 * 前一版本为JDK

java架构解密——Spring框架的ioc自我实现

在java的开发中,经常使用的框架当属SSH,而在这张框架中,我们首先接触到的就是神奇的Spring,虽然有N多前辈说Spring就是N多公共代码的集合,是帮助我们实现了,我们很久之前就想实现或者已经实现的好的点子的集合,但是作为一名合格工程师,怎么能不懂spring的底层实现呢!在今天咱们就一起探索Spring是怎么完成IOC工作的,也自己做一个简单Spring框架! 1,Spring中Bean的定义 作用:在spring中使用的bean,都有某些公共属性,此类就是对公共属性的定义 <span

开源项目几点心得,Java架构必会几大技术点

Java架构必会几大技术点 关于学习架构,必须会的几点技术 1. java反射技术 2. xml文件处理 3. properties属性文件处理 4. 线程安全机制 5. annocation注解 6. 设计模式 7. 代理机制(aop) 8. serlvet基础(过滤器等等) 几样比较实用的技术: 1. 模板语言freemarker 2. ognl 3. gson json工具类 大家对于几大框架望而生畏,实际上只要明白他的原理,就会触类旁通,在这里我说说自己的几点拙见! MVC层(Strut

Java架构师必须掌握的七大知识点

Java架构师主要需要做哪些工作呢? 1.负责设计和搭建软件系统架构(平台.数据库.接口和应用架构等),解决开发中各种系统架构问题. 2.优化现有系统的性能,解决软件系统平台关键技术问题攻关.核心功能模块设计.核心代码开发. 3.在项目需求不断细化的工程中校正整体的架构设计,以及详细模块拆分设计. 4.营造技术学习氛围,带领团队不断完善开发开发方法及流程,提升开发效率与质量,加强技术标准及规范. 5.带领团队攻克例如大数据量.高并发.高稳定性等带来的各种挑战及技术难关. 6.责任心强,有团队合作

Java架构师学习路线

想要成为Java架构师,除了需要对自身的职业规划有着清楚的认识,还需为自己量身定制一份Java架构师学习路线. 精通Java技能,不仅能让你找到一份心仪的工作,还能让你在Java架构师的道路上走的更远.Java架构师学习路线不只是指对自己的工作方向有一个大致的规划,还需要对知识技能进行一个系统的梳理. 2018年,TIOBE通过分析谷歌.百度和YouTube等平台的数据发现,Java使用人数占据15.37%,位居十大编程语言之首.Java由于其可移植性.可扩展性和庞大的用户社区,受到广泛程序员与