1、spring概念和原理:
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充。
1.1、什么是Aop
AOP是Aspect-oriented programming 面向切面(方面)的编程的简写。
AOP的实现可以把业务逻辑和系统级的服务进行隔离,使业务逻辑跟各个系统级服务的耦合度降低,从而提高程序的重用性和开发效率。
名词解释:
业务逻辑: 某个类的某个方法本身要实现的功能。
系统级的服务: 系统的日志、事务、权限验证。
1.2、怎样实现Aop
AOP的底层实现的原理都是动态代理。
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法。
案例:JDKProxyTest
public interface UserDao { public void addUser(); public void searchUser(); }
public class UserDaoImpl implements UserDao { @Override public void addUser() { /** * 系统级功能 */ // System.out.println("判断用户操作添加用户的权限"); /** * 业务逻辑 */ System.out.println("添加用户 ..."); int i = 1/0 ; /** * 系统级功能 */ // System.out.println("写入添加用户的日志 "); } @Override public void searchUser() { System.out.println("判断用户操作查询用户的权限"); int i = 1/0 ; System.out.println("查询用户 ..."); // System.out.println("写入查询用户的日志 "); } }
@Test public void testJDKProxy(){ //实例化目标对像 final UserDao target = new UserDaoImpl(); UserDao proxy = (UserDao)Proxy.newProxyInstance( //目标类ClassLoader,定义了由哪个ClassLoader对象来生成代理对象进行加载 target.getClass().getClassLoader(), //目标类的接口,一个Iterface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口 //给它,那这代理对象就宣称实现该接口(多态),这样我就能够调用这组接口中的方法 target.getClass().getInterfaces(), //实现Invocation接口,一个invocationHandler对象,当动态代理调用方法的时候 //会关联到一个invocationHandler对象上 new InvocationHandler(){ /** * proxy : 指我们所代理的那个真实的对象 * method : 指我们所要调用真实对象的某个方法的Method对象 * params : 指调用真实对象某个方法时接受的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] params) throws Throwable { System.out.println("判断用户操作添加用户的权限"); System.out.println("-" + method.getName()); Object result = method.invoke(target, params); //目标方法 System.out.println("写入添加用户的日志 "); return result; } }); proxy.addUser(); }
注意:动态代理有两种方式:jdk动态代理 /cglib动态代理
jdk的动态代理机制只能代理实现了接口的类
cglib的动态代理既可以代理实现了接口的类,也可以代理没有实现接口的类
cglib的动态代理的例子略。
1.3、Aop相关专业术语
* 切面(Aspect) : 横切关注点。就是交叉在各个业务逻辑中的系统服务(被模块化),类似于安全验证、事务处理、日志记录都可以理解为切面。
* 织入(weaving) : 就是将切面代码插入到目标对象某个方法的过程,相当于我们在jdk动态代理里面的 invocationHandler接口方法的内容 。
* 连接点(JointPoint) : 理论上可能被切面织入的所有方法 ,比如addUser(), searchUser()的方法前、方法后或抛异常后等等。通常所有方法都可以被称为连接点。
* 切入点(PointCut) : 就是实际上被切面织入的方法。
* 目标对象(target) : 就是切入点和连接点所属的类 UserDaoImpl,被通知的对象。
* 通知(Advice) : 就是切面的实现,切面必须要完成的工作。
* 代理(Proxy) : 向目标对象应用通知之后创建的对象。
* 顾问(Advisor) : 其实就是通知的一个封装和延伸,可以将通知以更为复杂的方式织入到某些方法中
将切面织入到目标对象的连接点方法,使连接点成为切入点