spring AOP的实现

1、AOP简介

面向切面编程,把遍布应用各处的功能分离出来,形成可重复使用的组件。

2、术语

1、通知

定义切面是什么,在什么时候使用。通知除了要完成工作,还要说明是在什么时候完成的。是在方法调用之前?还是之后?通知分为5种类型。

before在方法调用之前执行
after在方法调用之后执行,无论成功与失败
after-returning在方法执行成功之后执行
after-throwing在方法抛出异常后执行
around在方法调用之前和之后执行

2、连接点

应用中需要应用通知的地方。连接点是应用中可以插入切面的一个点,这个点可以是调用方法时,也可以是抛出异常时。

3、切点

在何处织入。切点可以匹配一个或者多个连接点。

4、切面

通知和切点的结合,同时完成了切面的全部功能,他是什么,在什么时候,什么地方完成了什么功能。

5、引入

允许向现有的类添加新的属性和方法。

6、织入

将切面应用到目标对象创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在生命周期有多个时期可以植入

(1)编译期

(2)类加载期

(3)运行期

3、编写切点

切点使用接口和实现类的全路径均可。

execution(* dao.TestService.testPlay(..))

execution:执行方法时触发

*:返回任意类型

dao.TestService:方法的全路径

testPlay():连接点

(..): 任意参数类型

4、使用XML配置AOP

1、依赖

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <!--切面依赖-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.13</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
     <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
  </dependencies>

2、创建接口UserDao接口和实现类

接口:

public interface UserDao {
    public void play();
}

实现类:

@Repository("userDao")
public class UserDaoImpl implements UserDao{
    @Override
    public void play() {
        System.out.println("running...");
    }
}

3、创建TestService和实现类(需要被增强的方法)

接口:(对testPlay()进行增强)

public interface TestService {
    public void testPlay();
}

实现类:

@Component("userService")
@Service("userService")
public class TestServiceImpl implements TestService{

    //注解注入,需要配置包扫描
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao;

    @Override
    public void testPlay() {
        System.out.println("test...");
        userDao.play();
    }
}

4、创建AOP类

public class AOPConfig {
    //前置通知
    public void playBefore(){
        System.out.println("AOP befort......");
    }

    //后置通知
    public void playAfter(){
        System.out.println("AOP fater......");
    }
}

5、配置applicationContext.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 https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--扫包-->
    <context:component-scan base-package="dao"/>

    <!--创建Bean-->
    <bean id="userDao" class="dao.UserDaoImpl"/>
    <bean id="userService" class="dao.TestServiceImpl"/>
    <bean id="aopConfig" class="dao.AOPConfig"/>

    <aop:config>
        <aop:aspect ref="aopConfig">
            <!--接口和实现类均可,需要导入依赖 aspectjweaver-->
            <aop:pointcut id="play" expression="execution(* dao.TestServiceImpl.testPlay(..))"/>
            <!--<aop:pointcut id="play" expression="execution(* dao.TestService.testPlay(..))"/>-->
            <aop:before pointcut-ref="play" method="playBefore"/>
            <aop:after pointcut-ref="play" method="playAfter"/>
            <!--<aop:around pointcut-ref="play" method="playBefore"/>-->
        </aop:aspect>
    </aop:config>

</beans>

6、测试

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        TestService service = (TestService) context.getBean("userService");
        service.testPlay();
    }
}

5、使用注解配置AOP(有参注入)

1、创建接口和实现类

接口:

public interface ReaderPeople {
    void MyThink(String thoughts);
    String getThought();
}

实现类

public class ReaderImpl implements ReaderPeople{
    private String thought;
    @Override
    public void MyThink(String thoughts) {
        System.out.println("my love");
        this.thought = thoughts;
    }
    public String getThought(){
        return thought;
    }
}

2、创建增强接口和实现类

接口:

public interface ReadThough {
    public void interceptThoughts(String thoughs);
    public String printThoughts();
    public void interceptThoughtsAfter(String thought);
}

实现类:


@Aspect //注解
public class ReadThoughImpl implements ReadThough{
    private String thought;

    @Pointcut(value = "execution(* AOP.ReaderImpl.*(..))")
    public void pintdemo(){}

    @Before(value = "pintdemo() && args(thought)") //这里不能用and
    @Override
    public void interceptThoughts(String thought) {
        System.out.println("提前监听");
        this.thought = thought;
    }

    @Override
    public String printThoughts() {
        return this.thought;
    }

    @After(value = "pintdemo() && args(thought)")
    @Override
    public void interceptThoughtsAfter(String thought) {
        System.out.println("拦截之后...");
    }
}

3、applicationContext.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 https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--扫包-->
    <context:component-scan base-package="dao"/>

    <!--配置AOP注解-->
    <aop:aspectj-autoproxy/>
</beans>

4、测试

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    ReaderPeople reader = (ReaderPeople) context.getBean("reader");
    reader.MyThink("spring AOP");
    System.out.println(reader.getThought());
}

5、当使用AOP的切点有参数时,对应的所有通知方法也必须带有对应参数

感谢小赵同学的大力支持

注:以上内容来自书籍Spring实战

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值