您的位置:首页 > 运维架构 > 网站架构

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

2015-05-31 15:08 791 查看
在上篇博客中,大家和我一起研究了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;  
    }  
 
  private void before() {  
        System.out.println("Before");  
    }  
 
    private void after() {  
        System.out.println("After");  
    } 
	
	
}


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(类似于客户端的组装)就可以实现这样的功能!让功能的扩充变得简单!

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

成为一个优秀的架构人员,我们要学习的还有很多!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: