Spring中AOP的模拟实现
什么是AOP?
面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面
1.面向切面编程提供声明式事务管理
2.spring支持用户自定义的切面
面向切面编程(aop)是对面向对象编程(oop)的补充,
面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。
AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,
是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。
aop框架具有的两个特征:
1.各个步骤之间的良好隔离性
2.源代码无关性前提:要实现AOP的模拟就要知道动态代理,Spring中使用了两种动态代理方式,一种是基于JDK的动态代理,一种是基于CGlib的动态代理。为什么会有两种,那是因为JDK的动态代理只能是针对接口。
先看下面的代码dao层
package com.lbx.dao; import com.lbx.model.User; public interface UserDAO { public void save(User user); //public void delete(); }dao实现层
package com.lbx.dao.impl; import com.lbx.dao.UserDAO; import com.lbx.model.User; public class UserDAOImpl implements UserDAO { @Override public void save(User user) { System.out.println("a user saved!!!"); } /*public void delete(){ System.out.println("UserDAOImpl.delete()"); } */ }现在我们要在User的save之前和之后做一些处理(拦截器),我们先看一种最简单的方法(在类中加代码)
package com.lbx.dao.impl; import com.lbx.dao.UserDAO; import com.lbx.model.User; public class UserDAOImpl1 implements UserDAO { @Override public void save(User user) { System.out.println("method start...."); System.out.println("a user saved!!!"); System.out.println("method stoped..."); } }显然,这是可以的,但是这样明显就不好,第一代码没可重用性,第二这是在知道源码的情况下,现实中我们有很多情况都不知道源码,在这种情况下,明显这方式就不行了。下面就是第二种解决方案:
package com.lbx.dao.impl; import com.lbx.model.User; public class UserDAOImpl2 extends UserDAOImpl{ public void save(User user) { System.out.println("method start...."); super.save(user); System.out.println("method stoped....."); } }先让一个类实现了那个接口,然后要用的类继承那个实现类,这样也可以达到目的(其实这就是一种“组合模式”),这种方式在一定的程度上是利用的资源,代码的重用性。但是还是不好,当我们要做很多的处理的时候,这样我们就要组合和多的类,明显就不好。下面是第三种:使用动态代理。 先看处理方法(拦截器)
package com.lbx.interceptor; public class UserInterceptor { //第一个拦截方法 public void method1(){ System.out.println("UserInterceptor.method1()"); } //第二个拦截方法 public void method2(){ System.out.println("UserInterceptor.method2()"); } }产生代理的类,实现InvocationHandler接口
package com.lbx.interceptor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyHandler implements InvocationHandler { //创建需要代理的目标对象 private Object targer; //创建拦截器的实例 UserInterceptor u = new UserInterceptor(); public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; //if(method.getName().equals("save")){ u.method1(); result = method.invoke(targer, args); u.method2(); //}else{ //result = method.invoke(targer, args); //} return result; } //用于设置传人目标对象的方法 public void setTarger(Object o){ this.targer = o; } }获得代理的实例类
package com.lbx.interceptor; import java.lang.reflect.Proxy; import com.lbx.dao.impl.UserDAOImpl; public class UserProxyFactory { public static Object getProxy(Object object){ ProxyHandler p = new ProxyHandler(); p.setTarger(object); return Proxy.newProxyInstance(UserDAOImpl.class.getClassLoader(), object.getClass().getInterfaces(), p); } }服务层使用动态代理
package com.lbx.service; import com.lbx.dao.UserDAO; import com.lbx.dao.impl.UserDAOImpl; import com.lbx.interceptor.UserProxyFactory; import com.lbx.model.User; public class UserService { //private UserDAO userDAO = new UserDAOImpl1(); //第一种就是写死,直接在方法里写 //private UserDAO userDAO = new UserDAOImpl2(); //第二种就是通过继承来实现(方法执行前后加一些业务逻辑) //private UserDAO userDAO = new UserDAOImpl3(); //第三种是通过组合来完成的 UserDAO userDAO = new UserDAOImpl(); UserDAO u = null; Object object = UserProxyFactory.getProxy(userDAO); /*public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; }*/ /*public void add(User user){ this.userDAO.save(user); }*/ public void add(User user){ if(object instanceof UserDAO){ u = (UserDAO)object; } u.save(user); //u.delete(); } }
相关推荐
也许不会看见 2020-07-08
HappyHeng 2020-06-25
也许不会看见 2020-06-28
zhongliwen 2020-05-11
也许不会看见 2020-05-04
方志朋 2020-05-01
横云断岭 2020-04-17
Justagreenonion 2020-03-07
容数据服务集结号 2020-02-20
itjavashuai 2020-02-14
smalllove 2020-02-14
haidaoxianzi 2020-01-12
neweastsun 2019-12-29
咻pur慢 2019-12-25
neweastsun 2019-11-09
Julywhj 2019-11-06
lttXiangFangJia 2019-06-02
横云断岭 2020-04-26