Spring中AOP的模拟实现

什么是AOP?
面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面
1.面向切面编程提供声明式事务管理
2.spring支持用户自定义的切面

面向切面编程(aop)是对面向对象编程(oop)的补充,
面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。
AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,
是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。

aop框架具有的两个特征:
1.各个步骤之间的良好隔离性
2.源代码无关性
前提:要实现AOP的模拟就要知道动态代理,Spring中使用了两种动态代理方式,一种是基于JDK的动态代理,一种是基于CGlib的动态代理。为什么会有两种,那是因为JDK的动态代理只能是

针对接口。
 
先看下面的代码dao层
Java代码    
1. package com.lbx.dao;  
2.  
3. import com.lbx.model.User;  
4.  
5. public interface UserDAO {  
6.     public void save(User user);  
7.     //public void delete();  
8. } 
 dao实现层
Java代码    
1. package com.lbx.dao.impl;  
2.  
3. import com.lbx.dao.UserDAO;  
4. import com.lbx.model.User;  
5.  
6. public class UserDAOImpl implements UserDAO {  
7.  
8.     @Override 
9.     public void save(User user) {  
10.           
11.         System.out.println("a user saved!!!");  
12.  
13.     }  
14.       
15.     /*public void delete(){ 
16.         System.out.println("UserDAOImpl.delete()"); 
17.     } 
18. */ 
19. } 
 现在我们要在User的save之前和之后做一些处理(拦截器),我们先看一种最简单的方法(在类中加代码)
Java代码    
1. package com.lbx.dao.impl;  
2.  
3. import com.lbx.dao.UserDAO;  
4. import com.lbx.model.User;  
5.  
6. public class UserDAOImpl1 implements UserDAO {  
7.  
8.     @Override 
9.     public void save(User user) {  
10.           
11.         System.out.println("method start....");  
12.           
13.         System.out.println("a user saved!!!");  
14.           
15.         System.out.println("method stoped...");  
16.  
17.     }  
18.  
19. } 
 显然,这是可以的,但是这样明显就不好,第一代码没可重用性,第二这是在知道源码的情况下,现实中我们有很多情况都不知道源码,在这种情况下,明显这方式就不行了。下面就是第二

种解决方案:
Java代码    
1. package com.lbx.dao.impl;  
2.  
3. import com.lbx.model.User;  
4.  
5. public class UserDAOImpl2 extends UserDAOImpl{  
6.  
7.     public void save(User user) {  
8.           
9.         System.out.println("method start....");  
10.         super.save(user);  
11.         System.out.println("method stoped.....");  
12.           
13.     }  
14.  
15. } 
 先让一个类实现了那个接口,然后要用的类继承那个实现类,这样也可以达到目的(其实这就是一种“组合模式”),这种方式在一定的程度上是利用的资源,代码的重用性。但是还是不好

,当我们要做很多的处理的时候,这样我们就要组合和多的类,明显就不好。下面是第三种:使用动态代理。                       先看处理方法(拦截器)
Java代码    
1. package com.lbx.interceptor;  
2.  
3. public class UserInterceptor {  
4.  
5.     //第一个拦截方法  
6.     public void method1(){  
7.         System.out.println("UserInterceptor.method1()");  
8.     }  
9.       
10.     //第二个拦截方法  
11.     public void method2(){  
12.         System.out.println("UserInterceptor.method2()");  
13.     }  
14.       
15. } 
 产生代理的类,实现InvocationHandler接口
Java代码    
1. package com.lbx.interceptor;  
2.  
3. import java.lang.reflect.InvocationHandler;  
4. import java.lang.reflect.Method;  
5.  
6. public class ProxyHandler implements InvocationHandler {  
7.       
8.     //创建需要代理的目标对象  
9.     private Object targer;  
10.     //创建拦截器的实例  
11.     UserInterceptor u = new UserInterceptor();  
12.       
13.     public Object invoke(Object proxy, Method method, Object[] args)  
14.             throws Throwable {  
15.         Object result = null;  
16.  
17.         //if(method.getName().equals("save")){  
18.             u.method1();  
19.             result = method.invoke(targer, args);  
20.             u.method2();  
21.         //}else{  
22.             //result = method.invoke(targer, args);  
23.         //}  
24.           
25.         return result;  
26.     }  
27.       
28.     //用于设置传人目标对象的方法  
29.     public void setTarger(Object o){  
30.         this.targer = o;  
31.     }  
32.  
33. } 
 获得代理的实例类
Java代码    
1. package com.lbx.interceptor;  
2.  
3. import java.lang.reflect.Proxy;  
4.  
5. import com.lbx.dao.impl.UserDAOImpl;  
6.  
7. public class UserProxyFactory {  
8.  
9.     public static Object getProxy(Object object){  
10.         ProxyHandler p = new ProxyHandler();  
11.         p.setTarger(object);  
12.         return Proxy.newProxyInstance(UserDAOImpl.class.getClassLoader(), object.getClass().getInterfaces(), p);  
13.     }   
14.       
15. } 
 服务层使用动态代理
Java代码    
1. package com.lbx.service;  
2.  
3. import com.lbx.dao.UserDAO;  
4. import com.lbx.dao.impl.UserDAOImpl;  
5. import com.lbx.interceptor.UserProxyFactory;  
6. import com.lbx.model.User;  
7.  
8. public class UserService {  
9.       
10.     //private UserDAO userDAO = new UserDAOImpl1();   //第一种就是写死,直接在方法里写  
11.     //private UserDAO userDAO = new UserDAOImpl2();     //第二种就是通过继承来实现(方法执行前后加一些业务逻辑)  
12.     //private UserDAO userDAO = new UserDAOImpl3();       //第三种是通过组合来完成的  
13.     UserDAO userDAO = new UserDAOImpl();  
14.     UserDAO u = null;  
15.       
16.     Object object = UserProxyFactory.getProxy(userDAO);  
17.       
18.     /*public UserDAO getUserDAO() { 
19.         return userDAO; 
20.     } 
21. 
22.     public void setUserDAO(UserDAO userDAO) { 
23.         this.userDAO = userDAO; 
24.     }*/ 
25.  
26.     /*public void add(User user){ 
27.         this.userDAO.save(user); 
28.     }*/ 
29.       
30.     public void add(User user){  
31.         if(object instanceof UserDAO){  
32.             u = (UserDAO)object;  
33.         }  
34.         u.save(user);  
35.         //u.delete();  
36.     }  
37.       
38. } 

 

 

你可能感兴趣的:(java,spring,AOP,object,user,Class)