Spring框架-4(AOP)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Utzw0p0985/article/details/79125110
0?wx_fmt=png

本文作者

0?wx_fmt=png

22

1-2018

zho007

博客:

https://www.jianshu.com/u/e9cb5fd3aaa8

声明:本文由作者 zho007 授权发布,未经原作者允许请勿转载

 看到上面蓝色字了吗,点下吧

系列文章:


  1. Spring框架-1(基础)

  2. Spring框架-2(IOC上)

  3. Spring框架-3(IOC下)

  4. Spring框架-4(AOP)

  5. Spring框架-5(JDBC模板&Spring事务管理)

  6. Spring框架-6(SpringMvc)

  7. Spring框架-7(搭建SSM)

  8. Spring框架-8(SpringMVC2)


日更一篇~

0?wx_fmt=png

前言

前面提到AOP可以在不修改源代码的前提下,对程序进行增强,AOP的底层实现其实是JDK的动态代理和CGLIB。那么这篇博客将入门AOP使用配置文件的用法和注解的用法。

我们这篇文章要学什么先看下思维导图吧:

0?wx_fmt=png

动手之前先了解一些术语

  1. Joinpoint(连接点)   -- 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点

  2. Pointcut(切入点)        -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义

  3. Advice(通知/增强)    -- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

  4. Introduction(引介) -- 引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field

  5. Target(目标对象)     -- 代理的目标对象

  6. Weaving(织入)      -- 是指把增强应用到目标对象来创建新的代理对象的过程

  7. Proxy(代理)        -- 一个类被AOP织入增强后,就产生一个结果代理类

  8. Aspect(切面)           -- 是切入点和通知的结合,以后咱们自己来编写和配置的

配置文件入门程序

1.需求

现在项目的某一个dao层对数据库有save,update,delete功能,现在我需要不改变功能代码的情况下,再这些功能前面输出log。

2.aspectJ的开发包

  • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

  • spring-aspects-4.2.4.RELEASE.jar

使用IDEA创建一个Spring项目,IDEA 会下载导入除了红框框以外的所有jar包。当然红框框哪个包也是需要的。既然IDEA不hi自动导入那么我们可以自己去下载导入。

0?wx_fmt=png

3.创建包结构,编写具体的接口和实现类,切面类

  • com.zhong.aopdemo

    CustomerDao           -- 接口

    CustomerDaoImpl       -- 实现类

    MyAspectXml           -- 切面类

public interface CustomDao {
   void save();
   void update();
   void delete();
}


public class CustomDaoImpl implements CustomDao {
   @Override
   public void save() {
       System.out.println("保存信息");
   }
   @Override
   public void update() {
       System.out.println("更新信息");
   }
   @Override
   public void delete() {
       System.out.println("删除信息");
   }
}


public class MyAspectXml {
   // 定义通知
   public void log() {
       System.out.println("记录日志...");
   }
}

4.配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

   <bean id="customDao" class="com.zhong.aopdemo.CustomDaoImpl"/>
   <bean id="myAspectXml" class="com.zhong.aopdemo.MyAspectXml"/>
   <aop:config>
       <!-- 引入切面类 -->
       <aop:aspect ref="myAspectXml">
           <!-- 定义通知类型:切面类的方法和切入点的表达式 -->
           <aop:before method="log" pointcut="execution(public * com.zhong.aopdemo.CustomDaoImpl.save(..))"/>
           <aop:before method="log" pointcut="execution(public * com.zhong.aopdemo.CustomDaoImpl.update(..))"/>
           <aop:before method="log" pointcut="execution(public * com.zhong.aopdemo.CustomDaoImpl.delete(..))"/>
       </aop:aspect>
   </aop:config>
</beans>

5.运行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config.xml")
public class Demo {
   @Resource(name="customDao")
   private CustomDao customDao;
   @Test
   public void test() {
       customDao.save();
       customDao.update();
       customDao.delete();
   }
}
运行结果

记录日志...

保存信息

记录日志...

更新信息

记录日志...

删除信息

看到结果,没问题那么我们的入门程序成功写完了。我们现在成功在save,update,delete这三个方法前记录了日志

分析一些术语

切入点的表达式

再配置切入点的时候,需要定义表达式,重点的格式如下:execution(public * *(..)),具体展开如下:

  1. 切入点表达式的格式如下:

  • execution([修饰符] 返回值类型 包名.类名.方法名(参数))

修饰符可以省略不写,不是必须要出现的。

返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。

包名例如:com.itheima.demo3.BookDaoImpl

  • 首先com是不能省略不写的,但是可以使用 * 代替

  • 中间的包名可以使用 * 号代替

  • 如果想省略中间的包名可以使用 ..

类名也可以使用号代替,也有类似的写法:DaoImpl

方法也可以使用 * 号代替

参数如果是一个参数可以使用*号代替,如果想代表任意参数使用 ..

AOP的通知类型

1.前置通知

  • 在目标类的方法执行之前执行。

  • 配置文件信息:

  • 应用:可以对方法的参数来做校验

2.最终通知

  • 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。

  • 在配置文件中编写具体的配置:

  • 应用:例如像释放资源

3.后置通知

  • 方法正常执行后的通知。      

  • 在配置文件中编写具体的配置:

  • 应用:可以修改方法的返回值

4.异常抛出通知

  • 在抛出异常后通知

  • 在配置文件中编写具体的配置:

  • 应用:包装异常的信息

5.环绕通知

  • 方法的执行前后执行。

  • 在配置文件中编写具体的配置:

  • 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。

注解方式实现

1.注解定义切面类

1.添加切面和通知的注解

  • @Aspect                   -- 定义切面类的注解

2.通知类型(注解的参数是切入点的表达式)

- @Before               -- 前置通知
- @AfterReturing        -- 后置通知
- @Around               -- 环绕通知
- @After                -- 最终通知
- @AfterThrowing        -- 异常抛出通知


@Component
@Aspect
public class MyAspectXml {
   // 定义通知
   @Before("execution(public * com.zhong.aopdemo.CustomDaoImpl.save(..))")
   public void log() {
       System.out.println("记录日志...");
   }
}

2.修改配置文件,给使用的类加上Component注解

<?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:aop="http://www.springframework.org/schema/aop"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

   <context:component-scan base-package="com.zhong.aopdemo"/>
   <!--在配置文件中开启自动代理-->
   <aop:aspectj-autoproxy/>
</beans>

测试结果

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config.xml")
public class Demo {
   @Resource(name="customDao")
   private CustomDao customDao;
   @Test
   public void test() {
       customDao.save();
   }
}

结果

记录日志...

保存信息

这就成功了。其实写到这里都是一些基础的东西。从配置文件到注解方式,可见注解是多么的强大。多么的方便,如果各位不太懂注解,建议先去熟悉熟悉注解


0?wx_fmt=jpeg

刘某人程序员

个人微信:Android_LiuGuiLin

新浪微博:@刘某人程序员

0?wx_fmt=jpeg

看看我的分享

  长按二维码关注

0?wx_fmt=png 0?wx_fmt=png


猜你喜欢

转载自blog.csdn.net/Utzw0p0985/article/details/79125110