二)Spring AOP编程思想与动态代理

一。aop编程思想
  1.面向切面,就是能够不动源码的情况下,从横切面切入新的代码功能。
  2.实现原理是动态代理
  动态代理的步骤
    a。写生产厂家,实现接口,代理只能代理接口
    b。动态代理类实现InvocationHandler接口,实现bind方法来绑定厂家,重写invoke方法
    c。消费者找动态代理类来获取商品消费
  3.aop的作用:是将系统级别的重复的操作统一实现,节省代码,扩展性更好
    例如:系统日志,系统非法访问,系统权限,系统事务

二。spring怎么实现AOP
  1。在spring的配置文件中加入aop的schema,并且打开aop的注解开关

    <!-- 开启aop的注解模式 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

  2。pom.xml中导入依赖spring-aop,spring-aspects

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>

  3。写一个aop的切面类,加上注解@comptent @Aspect
  4。在切面类中写切入的方法,在放上加上注解@Before @After @Around

实例1:动态代理

手机工厂生产的手机有发短信、打电话等功能,如果通过代理拿货,可以赠送自拍杆、免费贴膜等。

IPhoneFactory.java
package com.proxy;

public interface IPhoneFactory {

    void mobile();

    void mobile2();
    
    void mobile3();
}
PhoneFactory.java
package com.proxy;

public class PhoneFactory implements IPhoneFactory {
    public void mobile(){
        System.out.println("我是iphone XXX");
    }
    
    public void mobile2(){
        System.out.println("我可以打电话");
    }
    
    public void mobile3(){
        System.out.println("我可以发信息");
    }
}

  代理类 MyProxy.java

package com.proxy;

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

public class MyProxy implements InvocationHandler {

    private Object obj;// 要代理的目标产品,用object表示可以代理任何类型

    public Object bind(Object o) {
        this.obj = o;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("给手机贴膜");
        Object result = method.invoke(obj, new Object[]{});//是厂家的产品的原始功能
        System.out.println("赠送自拍杆");
        return result;
    }

}

  调用代码 Test.java

package com.proxy;

public class Test {
    public static void main(String[] args) {
        MyProxy mp = new MyProxy();
        IPhoneFactory iphone = (IPhoneFactory)mp.bind(new PhoneFactory());
        iphone.mobile3();
    }
}

实例2:aop面向切面

IStudentDAO.java
package com.aop;

public interface IStudentDAO {

    void addStudent();

    void delStudent();

    void updateStudent();

    void queryStudent();

}
StudentDAO.java
package com.aop;

import org.springframework.stereotype.Repository;

@Repository("stuDAO")
public class StudentDAO implements IStudentDAO {
    public void addStudent(){
        System.out.println("新增学员");
    }
    public void delStudent(){
        int i=1/0;
        System.out.println("删除学员");
    }
    
    public void updateStudent(){
        System.out.println("修改学员");
    }
    
    public void queryStudent(){
        System.out.println("查询学员");
    }
}

 切面类 

TranscationAOP.java
package com.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect//注册为一个切面
@Component
public class TranscationAOP {
    /**
     * 表示在方法执行前的切入
     * 第一个*表示方法的返回类型
     * 第二个*表示该包下所有的类
     * 第三个*表示类中所有的方法
     * (..)表示任意参数类型
     */
//    @Before("execution(* com.aop.*.*(..))")
//    public void beforeDAO(){
//        System.out.println("开启事务");
//    }
    
//    @After("execution(* com.aop.*.*(..))")
//    public void afterDAO(){
//        System.out.println("事务提交");
//    }

    /**
     * 前后切入
     * @param pjp 切入点
     */
    @Around("execution(* com.aop.*.*(..))")
    public void aroundDAO(ProceedingJoinPoint pjp){
        System.out.println("开启事务");
        try {
            pjp.proceed();//原方法正在执行
        } catch (Throwable e) {
            System.out.println("业务发生异常"+e.getMessage());
            System.out.println("事务回滚");
            e.printStackTrace();
            return;
        }
        System.out.println("事务提交");
    }
}

调用代码 

Test.java
package com.aop;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        BeanFactory bf = new ClassPathXmlApplicationContext("beans.xml");
        IStudentDAO stuDAO =  (IStudentDAO) bf.getBean("stuDAO");
        stuDAO.delStudent();
    }
}

 配置文件 beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 打开spring的注解功能 -->
    <context:annotation-config></context:annotation-config>
    <!-- 告诉spring到哪些包下去扫描bean对象 -->
    <context:component-scan base-package="com"></context:component-scan>
    <!-- 开启aop的注解模式 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <!-- <bean id="bt" class="com.bean.BeanTest"></bean> -->

    <!-- <bean id="stuDAO" class="com.dao.StudentDAO"></bean> -->
    <!-- <bean id="stuMysqlDAO" class="com.dao.StudentMysqlDAO"></bean> -->

    <!-- <bean id="stuSer" class="com.service.StudentService"> -->
    <!-- <property name="stuDAO"> -->
    <!-- <ref bean="stuMysqlDAO" /> -->
    <!-- </property> -->
    <!-- </bean> -->

    <!-- <bean id="stuControl" class="com.control.StudentControl"> -->
    <!-- <property name="stuSer"> -->
    <!-- <ref bean="stuSer" /> -->
    <!-- </property> -->
    <!-- </bean> -->
</beans>

  依赖 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>spring06</groupId>
    <artifactId>spring06</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
    </dependencies>
</project>
原文地址:https://www.cnblogs.com/wlxslsb/p/10791322.html