3-Spring AOP

AOP

1- What is AOP

  • AOP Aspect Oriented Programing Oriented Programming

  • AOP taken transverse extraction mechanism replacing the traditional longitudinal succession repetitive coding system (performance monitoring, transaction management, security check, cache).

2-AOP underlying implementation principle

3-AOP related terms

public class USerDaoImpl implements UserDao{
    public void save(User user){
    
    }
    public void update(User user){
    
    }
    public void find( ){
    
    }
    public void delete(User user){
    
    }
}

JoinPoint (connection points) : refers to the point can be intercepted. CRUD these methods can be enhanced, these methods are called point of attachment.

Pointcut (entry point) : refers to the real point was blocked. Just want to save methods of enhanced (do check the permissions), save method is called an entry point.

Advice (notification) : After intercepting do. Methods to save calibration method, called the notification permission to check.

Target (target) : enhanced object

Weaving (weaving) : The procedure applied to the Advice of Target. Check the permissions applied to the process of the Save method of UserDaoImpl.

The Proxy (Agent) : enhanced after being applied, resulting in a proxy object.

Aspect (section) : is a combination of entry points and notification.

4.JDK dynamic proxy

Change the code needs to import test jar package Juint

public interface UserDao {
    public void save();

    public void update();

    public void delete();

    public void find();
}

* * *
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("保存用户...");
    }

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

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

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

* * *
public class MyJdkProxy implements InvocationHandler{
    private UserDao userDao;

    public MyJdkProxy(UserDao userDao){
        this.userDao = userDao;
    }

    public Object createProxy(){
        Object proxy = Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this);
        return proxy;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("权限校验...");
            return method.invoke(userDao,args);
        }
        return method.invoke(userDao,args);
    }
}

* * *
public class SpringDemo1 {
    @Test
    public void demo1(){
        UserDao userDao = new UserDaoImpl();

        UserDao proxy = (UserDao)new MyJdkProxy(userDao).createProxy();
        proxy.save();
        proxy.update();
        proxy.delete();
        proxy.find();
    }
}

5. Use generated proxy CGLIB

pom.xml核心jar包
<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
     <!--aop联盟的包-->
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>
    <!--spring aop的包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
public class ProductDao {
    public void save(){
        System.out.println("保存商品...");
    }

    public void update(){
        System.out.println("修改商品...");
    }

    public void delete(){
        System.out.println("删除商品...");
    }

    public void find(){
        System.out.println("查询商品...");
    }
}

* * *
public class MyCglibProxy implements MethodInterceptor{

    private ProductDao productDao;

    public MyCglibProxy(ProductDao productDao){
        this.productDao = productDao;
    }

    public Object createProxy(){
        // 1.创建核心类
        Enhancer enhancer = new Enhancer();
        // 2.设置父类
        enhancer.setSuperclass(productDao.getClass());
        // 3.设置回调
        enhancer.setCallback(this);
        // 4.生成代理
        Object proxy = enhancer.create();
        return proxy;
    }

    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("权限校验===================");
            return methodProxy.invokeSuper(proxy,args);
        }
        return methodProxy.invokeSuper(proxy,args); //调用父类
    }
}

* * *
public class SpringDemo2 {

    @Test
    public void demo1(){
        ProductDao productDao = new ProductDao();

        ProductDao proxy = (ProductDao) new MyCglibProxy(productDao).createProxy();
        proxy.save();
        proxy.update();
        proxy.delete();
        proxy.find();
    }
}

6- agent knowledge summary

1- Spring at runtime, generate dynamic proxy object, no special compilers

2-Spring AOP underlying objective is Bean JDK dynamic proxy or by dynamic proxy technology CGLib
performing lateral weaving.

  • If the target object implements a number of interfaces, spring java.lang.reflect.Proxy use the JDK class
    agent.
  • If the target object does not implement any interfaces subclass, spring CGLIB libraries generated using the target object.

3-程序中应优先对接口创建代理,便于程序解耦维护

4-标记为final的方法,不能被代理,因为无法进行覆盖

  • JDK动态代理,是针对接口生成子类,接口中方法不能使用final修饰
  • CGLib 是针对目标类生产子类,因此类或方法 不能使final的

5-Spring只支持方法连接点,不提供属性连接

6-Spring AOP增强类型

1-前置通知

  • 在目标方法执行前实施增强

2-后置通知

  • 在目标方法执行后实施增强

3-环绕通知

  • 在目标方法执行前后实施增强

4-异常抛出通知

  • 在方法抛出异常后实施增强

7- Spring AOP切面类型

1.Advisor : 代表一般切面,Advice本身就是一个切面,对目标类所有方法进
行拦截。

public interface StudentDao {
    public void find();

    public void save();

    public void update();

    public void delete();
}

* * *
public class StudentDaoImpl implements  StudentDao {
    public void find() {
        System.out.println("学生查询...");
    }

    public void save() {
        System.out.println("学生保存...");
    }

    public void update() {
        System.out.println("学生修改...");
    }

    public void delete() {
        System.out.println("学生删除...");
    }
}

* * *
public class MyBeforeAdvice implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("前置增强======================");
    }
}

* * *
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo3 {

    // @Resource(name="studentDao")
    @Resource(name="studentDaoProxy")
    private StudentDao studentDao;

    @Test
    public void demo1(){
        studentDao.find();
        studentDao.save();
        studentDao.update();
        studentDao.delete();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置目标类=======================-->
    <bean id="studentDao" class="com.imooc.aop.demo3.StudentDaoImpl"/>

    <!--前置通知类型=====================-->
    <bean id="myBeforeAdvice" class="com.imooc.aop.demo3.MyBeforeAdvice"/>

    <!--Spring的AOP 产生代理对象-->
    <bean id="studentDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!--配置目标类-->
        <property name="target" ref="studentDao"/>
        <!--实现的接口-->
        <property name="proxyInterfaces" value="com.imooc.aop.demo3.StudentDao"/>
        <!--采用拦截的名称-->
        <property name="interceptorNames" value="myBeforeAdvice"/>
        <property name="optimize" value="true"></property>
    </bean>
</beans>

2.PointcutAdvisor : 代表具有切点的切面,可以指定拦截目标类哪些方法

3.IntroductionAdvisor : 代表引介切面,针对引介通知而使用切面

Guess you like

Origin www.cnblogs.com/Guard9/p/11105503.html
Recommended