其他分享
首页 > 其他分享> > spring入门之Aop

spring入门之Aop

作者:互联网

springAop

描述:

​ Aspect Oriented Programming 的简写,译为“面向切面编程”。

AOP 用来封装多个类的公共行为,将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度。另外,AOP 还解决一些系统层面上的问题,比如日志、事务、权限等。

代理机制:

​ Spring 在运行期会为目标对象生成一个动态代理对象,并在代理对象中实现对目标对象的增强。

​ Spring AOP 的底层是通过以下 2 种动态代理机制,为目标对象(Target Bean)执行横向织入的。

代理技术 描述
JDK 动态代理 Spring AOP 默认的动态代理方式,若目标对象实现了若干接口,Spring 使用 JDK 的 java.lang.reflect.Proxy 类进行代理。
CGLIB 动态代理 若目标对象没有实现任何接口,Spring 则使用 CGLIB 库生成目标对象的子类,以实现对目标对象的代理。
切入点:

​ Spring AOP 只支持一种连接点类型:方法调用。您可能会认为这是一个严重的限制,但实际上 Spring AOP 这样设计的原因是为了让 Spring 更易于访问。如果需要使用其他类型的连接点(例如成员变量连接点),我们可以将 Spring AOP 与其他的 AOP 实现一起使用,最常见的组合就是 Spring AOP + ApectJ。

通知类型:

​ Spring AOP 按照通知(Advice)织入到目标类方法的连接点位置,为 Advice 接口提供了 6 个子接口,如下表。

通知类型 接口 描述
前置通知 org.springframework.aop.MethodBeforeAdvice 在目标方法执行前实施增强。
后置通知 org.springframework.aop.AfterReturningAdvice 在目标方法执行后实施增强。
后置返回通知 org.springframework.aop.AfterReturningAdvice 在目标方法执行完成,并返回一个返回值后实施增强。
环绕通知 org.aopalliance.intercept.MethodInterceptor 在目标方法执行前后实施增强。
异常通知 org.springframework.aop.ThrowsAdvice 在方法抛出异常后实施增强。
引入通知 org.springframework.aop.IntroductionInterceptor 在目标类中添加一些新的方法和属性。
切面类型:

Spring 使用 org.springframework.aop.Advisor 接口表示切面的概念,实现对通知(Adivce)和连接点(Joinpoint)的管理。

在 Spring AOP 中,切面可以分为三类:一般切面、切点切面和引介切面。

切面类型 接口 描述
一般切面 org.springframework.aop.Advisor Spring AOP 默认的切面类型。 由于 Advisor 接口仅包含一个 Advice(通知)类型的属性,而没有定义 PointCut(切入点),因此它表示一个不带切点的简单切面。 这样的切面会对目标对象(Target)中的所有方法进行拦截并织入增强代码。由于这个切面太过宽泛,因此我们一般不会直接使用。
切点切面 org.springframework.aop.PointcutAdvisor Advisor 的子接口,用来表示带切点的切面,该接口在 Advisor 的基础上还维护了一个 PointCut(切点)类型的属性。 使用它,我们可以通过包名、类名、方法名等信息更加灵活的定义切面中的切入点,提供更具有适用性的切面。
引介切面 org.springframework.aop.IntroductionAdvisor Advisor 的子接口,用来代表引介切面,引介切面是对应引介增强的特殊的切面,它应用于类层面上,所以引介切面适用 ClassFilter 进行定义。
代码实现:

(1)导入依赖

<dependencies>
    <!--spring AOP的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <!--springIOC的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>
</dependencies>

(2)创建一个名为 UserDao 的接口,代码如下。

public interface UserDao {
    public void add();
    public void delete();
    public void modify();
    public void get();
}

(3)创建 UserDao 的实现类 UserDaoImpl,代码如下。

public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("正在执行 UserDao 的 add() 方法……");
    }
    @Override
    public void delete() {
        System.out.println("正在执行 UserDao 的 delete() 方法……");
    }
    @Override
    public void modify() {
        System.out.println("正在执行 UserDao 的 modify() 方法……");
    }
    @Override
    public void get() {
        System.out.println("正在执行 UserDao 的 get() 方法……");
    }
}

(4)创建一个名为 UserDaoBeforeAdvice 的前置增强类,代码如下。

/**
* 增强代码
* MethodBeforeAdvice 前置增强
*
*/
public class UserDaoBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("正在执行前置增强操作…………");
    }
}

(5)在 src 目录下创建一个 Spring 的配置文件 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!--******Advisor : 代表一般切面,Advice 本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)*******-->
    <!-- 定义目标(target)对象 -->
    <bean id="userDao" class="net.biancheng.c.dao.impl.UserDaoImpl"></bean>
    <!-- 定义增强 -->
    <bean id="beforeAdvice" class="net.biancheng.c.advice.UserDaoBeforeAdvice"></bean>
    <!--通过配置生成代理 UserDao 的代理对象 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 设置目标对象 -->
        <property name="target" ref="userDao"/>
        <!-- 设置实现的接口 ,value 中写接口的全路径 -->
        <property name="proxyInterfaces" value="net.biancheng.c.dao.UserDao"/>
        <!-- 需要使用value:增强 Bean 的名称 -->
        <property name="interceptorNames" value="beforeAdvice"/>
    </bean>
</beans>

(6)创建一个名为 MainApp 的类,代码如下。

public class MainApp {
    public static void main(String[] args) {
        //获取 ApplicationContext 容器
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        //获取代理对象
        UserDao userDao = context.getBean("userDaoProxy", UserDao.class);
        //调用 UserDao 中的各个方法
        userDao.add();
        userDao.delete();
        userDao.get();
        userDao.modify();
    }
}

标签:Spring,入门,spring,AOP,springframework,切面,Aop,org,public
来源: https://www.cnblogs.com/zhaohongbing/p/16359208.html