一、AOP能解决什么问题

  

  业务层每个service都要管理事务,在每个service中单独写事务,就会产生很多重复性的代码,而且修改事务时,需要修改源码,不利于维护。为此,把横向重复的代码,纵向抽取形成公共的功能。

  横向重复,纵向抽取,这就是AOP思想。

二、AOP的原理

  1、aop是什么

    AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

    Spring Aop原理就是在程序运行时,使用动态代理技术,不修改源码,对原有方法进行增强。

  2、AOP的实现方式

      使用动态代理技术,常用的方式有两种。

    (1)基于接口的动态代理

      JDK官方提供,被代理类至少实现一个接口

/**
* 接口
*/
public interface UserService {
void save(User user);
}
/**
* 被代理类
*/
public class UserServiceImpl implements UserService{
@Override
public void save(User user){
System.out.println("保存用户"+user);
}
}
/**
* 生成代理对象的工厂
*/
public class ProxyFactory {
public ProxyFactory(UserService us) {
super();
this.us = us;
}
private UserServiceImpl userServiceImpl;
public UserService getUserServiceProxy() {
/**
* newProxyInstance方法的参数:
* ClassLoader:被代理对象的类加载器
* Class[]:字节码数组,用于让代理对象和被代理对象有相同方法
* InvocationHandler:用于提供增强的代码
*/
UserService proxyUserService = (UserService) Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(),
UserServiceImpl.class.getInterfaces(),
new InvocationHandler() {
/**
* 作用:执行被代理对象的任何接口方法都会经过该方法
* @param proxy 代理对象的引用
* @param method 当前执行的方法
* @param args 当前执行方法的参数
* @return 和被代理对象方法有相同的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("打开事务!");
Object invoke = method.invoke(userServiceImpl, args);
System.out.println("提交事务!");
return invoke;
}
});
return proxyUserService;
}
}
public class Test {
@Test
public void fun1(){
UserService us = new UserServiceImpl();
ProxyFactory factory = new ProxyFactory(us);
UserService usProxy = factory.getUserServiceProxy();
usProxy.save();
//代理对象与被代理对象实现了相同的接口
//代理对象 与 被代理对象没有继承关系
System.out.println(usProxy instanceof UserServiceImpl );//false
}
}

  (2)基于子类的动态代理

    第三方cglib,被代理类不能被final修饰

/**
* create方法的参数:
* Class:字节码,用于指定被代理对象的字节码。
* Callback:用于提供增强的代码,一般写该接口的子接口实现类:MethodInterceptor
*/
UserService cglibUserService = (UserService) Enhancer.create(UserServiceImpl.class, new MethodInterceptor() {
/**
* 执行被代理对象的任何方法都会经过该方法
* @param proxy
* @param method
* @param args
* 以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
* @param methodProxy :当前执行方法的代理对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//打开事务
System.out.println("打开事务!");
//调用原有方法
Object returnValue = methodProxy.invokeSuper(proxy, args);
//提交事务
System.out.println("提交事务!");
return returnValue;
}
});

三、AOP相关术语

四、AOP的使用

  1、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: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">

<!-- 1、配置被代理对象-->
<bean id="userService" class="com.demo.service.impl.UserServiceImpl"></bean>
<!-- 2、配置公共功能类 -->
<bean id="logger" class="com.demo.utils.Logger"></bean>
<!-- 3、配置AOP -->
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:pointcut id="pt" expression="(* com.demo.service.impl.*.*(..))"/>
<aop:before method="printLog" pointcut-ref="pt"></aop:before>
</aop:aspect>
</aop:config>
</beans>

 

  2、全注解配置方式

    pom.xml添加org.aspectj.aspectjweaver依赖

示例:

// 配置类
@Configuration
@ComponentScan(basePackages="com.demo") // 扫描包
@EnableAspectJAutoProxy // 开启注解aop
public class SpringConfiguration {
}

 // 切面类
@Component("logger")
@Aspect
@Order(0)
public class Logger {

// 任意包下的impl包中任意类的任意方法
@Pointcut("execution(* *..impl.*.*(..))")
private void pt(){}

@Before("pt()")
public void beforePrintLog(){
System.out.println("前置通知");
}
}
												

Spring基础之AOP的更多相关文章

  1. Spring基础系列--AOP织入逻辑跟踪

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9619910.html 其实在之前的源码解读里面,关于织入的部分并没有说清楚,那些前置.后 ...

  2. Spring基础系列-AOP源码分析

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...

  3. 【spring基础】AOP概念与动态代理详解

    一.代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...

  4. spring基础概念AOP与动态代理理解

    一.代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...

  5. Spring基础20——AOP基础

    1.什么是AOP AOP(Aspect-Oriented Programming)即面向切面编程,是一种新的方法论,是对那个传统OOP面向对象编程的补充.AOP的主要编程对象是切面(aspect),而 ...

  6. Spring基础系列--AOP实践

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9615720.html 本文目的是简单讲解下Spring AOP的使用. 推荐使用IDEA ...

  7. Spring基础只是—AOP的概念介绍

    Spring容器包含两个重要的特性:面向切面编程(AOP)和控制反转(IOC).面向切面编程是面向对象(OOP)的一种补充,在面向对象编程的过程中编程针对的目标是一个个对象,而面向切面编程中编程针对的 ...

  8. spring基础学习---aop

    1:无参aop下面为项目结构 2:通知类.MyAdvice package cn.edu.aop; import org.aspectj.lang.ProceedingJoinPoint; //通知类 ...

  9. Spring基础系列-Spring事务不生效的问题与循环依赖问题

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9476550.html 一.提出问题 不知道你是否遇到过这样的情况,在ssm框架中开发we ...

随机推荐

  1. codeforce 266c Below the Diagonal 矩阵变换 (思维题)

    C. Below the Diagonal You are given a square matrix consisting of n rows and n columns. We assume th ...

  2. [bzoj5329] P4606 [SDOI2018]战略游戏

    P4606 [SDOI2018]战略游戏:广义圆方树 其实会了圆方树就不难,达不到黑,最多算个紫 那个转换到圆方树上以后的处理方法,画画图就能看出来,所以做图论题一定要多画图,并把图画清楚点啊!! 但 ...

  3. Python(Pyautogui 模块)

    1.安装 pyautogui 模块 pip install pyautogui 2.pyautogui 模块相关操作 鼠标操作 # 获取屏幕宽和高 w,h = pyautogui.size() # 在 ...

  4. Spring Boot 整合 Dubbo和Zookeeper

    Spring Boot 整合 Dubbo和Zookeeper Spring Boot 整合 Dubbo和Zookeeper 环境介绍 Zookeeper 安装 启动 Dubbo admin 搭建 创建 ...

  5. GitHub上Asp.Net Core的源代码

    记录,备查. https://github.com/aspnet/AspNetCore/tree/master/src

  6. Java的Object.wait(long)在等待时间过去后会继续往后执行吗

    Java的Object.wait(long)在等待时间过去后会继续往后执行吗 Object.wait(long)方法相比于wait,多了个等待时长,那么当等待时长过去后,线程会继续往下执行吗? 单个线 ...

  7. CodeForces - 1209D Cow and Snacks 并查集

    CodeForces - 1209D 题意 现在n种点心,每种点心只有一份,有k位客人,每位客人有两种想要吃的点心,你可以安排他们进场的顺序,每位客人会吃掉所有他想要吃的,并且还没被吃掉的点心.如果客 ...

  8. Akko海洋之星

    今天(2020.5.14)入手Akko海洋之星84茶轴,开心呀~~ 考虑方面: 价格>键线分离>接线接口>轴体>键帽>材质 价格: 200~500之间入门级cherry轴 ...

  9. markdown:列表、表格、代码实现

    插入列表 1. dsf2. dsds 插入表格header 1 | header 2---|---row 1 col 1 | row 1 col 2row 2 col 1 | row 2 col 2 ...

  10. springData表关系:一对一

    一.编写两个实体类 1.一对一关系实现:a:使用外键关联 b:使用主键关联,两个表的主键相同 2.外键方案:配置关联关系:两个实体类互相关联,并且在关联的属性上添加一个@OneToOne代表一个对一个 ...