现在的位置: 首页 > 编程 > 正文

Spring(二)

2017年05月03日 编程 ⁄ 共 3669字 ⁄ 字号 暂无评论

1.1 AOP概述

1.1.1什么是AOP

  • AOP(Aspect Oriented Programing) 面向切面编程。
  • AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)。 

  • Spring的AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码。
  • AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译的时候提供横向代码的织入。

 

1.1.2AOP底层原理

  • 代理机制
    • 动态代理(JDK的动态代理)
      • JDK的动态代理,对实现了接口的类生成代理。  

 

1.1.3Spring的AOP代理

  • JDK动态代理:对实现了接口的类生成代理
  • CGLIB代理机制:对类生成代理  

 

1.1.4AOP的术语

  • joinpoint(连接点):所谓的连接点是指那些被拦截到的点。在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点。
  • pointcut(切入点):所谓的切入点是指我们要对那些joinpoint进行拦截的定义。
  • Advice(通知/增强):所谓通知是指拦截到joinpoint之后所要做的事情就是通知。通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)。
  • Introduction(引介):引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或属性。
  • Target(目标对象):代理的目标对象。
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。Spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入。
  • Proxy(代理):一个雷被AOP织入增强后,就产生了一个结果代理类。
  • Aspect(切面):是切入点和通知(引介)的结合。

 

1.2 AOP底层实现 

1.2.1JDK的动态代理

package cn.demo4;

public interface IUserDAO {
    public void add();
    public void update();
    public void delete();
    public void find();
}
package cn.demo4;

public class UserDAOImpl implements IUserDAO {

    @Override
    public void add() {
        System.out.println("添加用户");
    }

    @Override
    public void update() {
        System.out.println("修改用户");
    }

    @Override
    public void delete() {
        System.out.println("删除用户");
    }

    @Override
    public void find() {
        System.out.println("查询用户");
    }

}
package cn.demo4;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class UserDAOProxy implements InvocationHandler {
    
    private IUserDAO iUserDAO;
    public UserDAOProxy(IUserDAO iUserDAO){
        this.iUserDAO = iUserDAO;
    }
    
    public IUserDAO getProxy(){
        Object result = Proxy.newProxyInstance(iUserDAO.getClass().getClassLoader(), iUserDAO.getClass().getInterfaces(),this );
        return (IUserDAO) result;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(method.getName().equals("add")){
            System.out.println("日志记录");
            Object result = method.invoke(iUserDAO, args);
            System.out.println("日志记录");
            return result;
        }
        if(method.getName().equals("delete")){
            System.out.println("日志记录");
            Object result = method.invoke(iUserDAO, args);
            System.out.println("日志记录");
            return result;
        }
        return  method.invoke(iUserDAO, args);
    }
    
    



}
package cn.demo4;

import org.junit.Test;

public class TestDemo {
    @Test
    public void demo1(){
        IUserDAO iUserDAO = new UserDAOImpl();
        IUserDAO proxy = new UserDAOProxy(iUserDAO).getProxy();
        proxy.add();
        proxy.delete();
        proxy.find();
        proxy.update();
    }
}

 

1.2.2CGLIB动态代理

package cn.demo5;

public class ProductDAO {
    
    public void add(){
        System.out.println("添加商品");
    }
    
    public void delete(){
        System.out.println("删除商品");
    }
    
    public void update(){
        System.out.println("修改商品");
    }
    public void find(){
        System.out.println("查询商品");
    }
    
    
}
package cn.demo5;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class ProductDAOProxy implements MethodInterceptor{
    private ProductDAO productDAO;
    public ProductDAOProxy(ProductDAO productDAO){
        this.productDAO = productDAO;
    }
    
    public ProductDAO getProxy(){
        //创建CGLIB的核心类
        Enhancer enhancer = new Enhancer();
        //为其设置父类
        enhancer.setSuperclass(productDAO.getClass());
        //设置回调
        enhancer.setCallback(this);
        //创建代理
        return (ProductDAO) enhancer.create();
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if(method.getName().equals("add")){
            System.out.println("日志记录");
            return methodProxy.invokeSuper(proxy, args);
        }
        if(method.getName().equals("delete")){
            System.out.println("日志记录");
            return methodProxy.invokeSuper(proxy, args);
        }
        return methodProxy.invokeSuper(proxy, args);
    }
}
package cn.demo5;

import org.junit.Test;

public class TestDemo {
    @Test
    public void demo1(){
        ProductDAO proxy = new ProductDAOProxy(new ProductDAO()).getProxy();
        proxy.add();
        proxy.delete();
        proxy.find();
        proxy.update();
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

给我留言

您必须 [ 登录 ] 才能发表留言!

×