Spring从入门到入土——AOP就这么简单

这里写目录标题AOP什么是AOPAOP在Spring中的作用核心名词Spring中支持的五种类型的Advice使用Spring实现Aop第一种方式——通过Spring API实现业务接口和实现类增强类前置增强后置增强去Spring的文件中注册,并实现aop切入实现测试第二种方式:自定义类来实现Aop切入类去spring中配置测试第三种方式——使用注解注解实现的增强类在spring配置文件中,注册bean,并增加支持注解的配置
相关文章

跟着官网学spring—快速入门指南

跟着官网学Spring—构建RESTful Web服务

Spring从入门到入土——概述以及IOC理论推导

Spring从入门到入土——快速上手Spring

Spring从入门到入土——依赖注入(DI)

Spring从入门到入土——Bean的作用域

Spring从入门到入土——自动装配

Spring从入门到入土——使用注解

Spring从入门到入土——AOP就这么简单

Spring从入门到入土——代理模式

AOP
什么是AOP

​ 面向切面编程。通过预编译的方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型,利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各个部分的耦合度降低,提高程序的可重用性,同时提高了开发效率。

AOP在Spring中的作用

提供声明式事务;允许用户自定义切面

核心名词

横切关注点:横跨应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的地方,就是横切关注点,如:日志、安全、缓存、事务
切面:横切关注点被模块化的特性对象,即:它是一个类
通知:切面必须要完成的工作。即它是类中的一个方法
目标:被通知对象
代理:向目标对象应用通知以后创建的对象。
切入点:切面通知执行的“地点的定义
连接点:与切入点匹配的执行点

Spring中支持的五种类型的Advice

通知类型 连接点 实现接口
前置通知 方法前 org.springframework.aop.MethodBeforeAdvice
后置通知 方法后 org.springframework.aop.AfterReturningAdvice
环绕通知 方法前后 org.springframework.aop.MethodInterceptor
异常抛出通知 方法抛出异常 org.springframework.aop.ThrowsAdvice
引介通知 类中增加新方法属性 org.springframework.aop.IntroductionOnterceptor

即Aop在不改变原有代码的情况下,去增加新的功能

使用Spring实现Aop

使用AOP,需要导入一个依赖包

org.aspectj
aspectjweaver
1.9.4


第一种方式——通过Spring API实现
业务接口和实现类
public interface UserService {

public void add();

public void delete();

public void update();

public void search();

}

public class UserServiceImpl implements UserService{

@Override
public void add() {
System.out.println("增加用户");
}

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

@Override
public void update() {
System.out.println("更新用户");
}

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

增强类
前置增强
public class Log implements MethodBeforeAdvice {

//method : 要执行的目标对象的方法
//objects : 被调用的方法的参数
//Object : 目标对象
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");
}
}

后置增强
public class AfterLog implements AfterReturningAdvice {
//returnValue 返回值
//method被调用的方法
//args 被调用的方法的对象的参数
//target 被调用的目标对象
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了" + target.getClass().getName()
+"的"+method.getName()+"方法,"
+"返回值:"+returnValue);
}
}

去Spring的文件中注册,并实现aop切入实现


测试
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
userService.search();
}
}

Aop的重要性:很重要,一定要理解其中的思路

​ Spring的Aop就是将公共的业务(日志、安全)和领域业务结合起来,当执行领域业务时,将会把公共业务加起来,实现公共业务的重复利用,领域业务更加纯粹,程序员只需要专注领域业务。

​ 其本质还是动态代理

第二种方式:自定义类来实现Aop

目标业务不变依旧是userServiceImpl

切入类
public class DiyPointcut {

public void before(){
System.out.println("---------方法执行前---------");
}
public void after(){
System.out.println("---------方法执行后---------");
}

}

去spring中配置


测试
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
userService.add();
}
}

第三种方式——使用注解
注解实现的增强类
package com.zhonghu.config;

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;

@Aspect
public class AnnotationPointcut {
@Before("execution(* com.zhonghu.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("---------方法执行前---------");
}

@After("execution(* com.zhonghu.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("---------方法执行后---------");
}

@Around("execution(* com.zhonghu.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
System.out.println("签名:"+jp.getSignature());
//执行目标方法proceed
Object proceed = jp.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
}

在spring配置文件中,注册bean,并增加支持注解的配置

aop:aspectj-autoproxy:说明

通过aop创建的命名空间的声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被隐藏起来了
有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理

进行自动代理的创建工作,但具体实现的细节已经被隐藏起来了

有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理

冢狐


原创文章 87获赞 178访问量 1万+

关注
私信

展开阅读全文

作者:冢狐

相关推荐

Django 视图 – FBV 与 CBV

MYSQL 性能分析器 EXPLAIN 用法实例分析

MySQL联表查询基本操作之left-join常见的坑

linux shell 根据进程名获取pid的实现方法