AOP:

      aop切面编程,其实就是spring增强器的一个扩展,就是通过beanPostProcessor的after后置方式实现的,其中在after中把需要的bean通过放射+动态代理完成bean的替换,替换成代理bean。然后通过注册拦截器完成代理方式的执行;

    1、代理对象的创建过程(advice,切面、切点)

    2、通过jdk或cglib的方式生产代理对象(通过beanPostProcessor的after后置方式实现)

    3、执行方法回调的时候,会到字节码的文件中,直接找回到DynamicAdviceedInterceptor中的intercept方法,在这里执行

              4、在执行过程中,会生成之前定义好的通知拦截器,来执行

    Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

    

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。

  JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。

  CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

1、首先要注入 @EnableAspectJAutoProxy

@EnableAspectJAutoProxy
@ComponentScan(value = "com.flm")
public class Config {
}

2、创建service

@Component
public class UserServiceImpl implements UserService {
public UserServiceImpl(){
System.out.println("UserServiceImpl 构造方法 create ......");
}

@PostConstruct
private void rn(){
System.out.println("UserServiceImpl 使用@PostConstruct run... ......");
} @Override
public String test(){
System.out.println("aop test 业务逻辑....");
return "OK";
}
@Override
public void testData() {
System.out.println("testData 业务逻辑....");
}
}

3、启动类

public class APP {
public static void main(String[] args) {
// 方式1:指定xml启动
// ApplicationContext context = new ClassPathXmlApplicationContext("beans-context-content.xml");
// 方式二:指定配置类启动
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (Config.class); // 在spring容器获取bean
UserService userService = context.getBean(UserService.class);
// 执行要aop的接口
String rt = userService.test();
System.out.println(rt);
userService.testData();
}
}

4、自定义aop方法(原理)

@Component
public class AopPostProcessor implements BeanPostProcessor {
// 原理 BeanPostProcessor + jdk动态代理实现
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 判断哪个接口需要代理的 ,写死
if("userServiceImpl".equals(beanName)){
// 创建代理对象 , JDK代理是依赖接口的,有实现接口的为jdk代理,否则为 cglib代理
Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(), UserServiceImpl.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
// 判断哪个方法需要代理使用执行的,现在写死test
if("test".equals(method.getName())){
// 方法之前执行
System.out.println("invoke before ...");
// 执行方法
result = method.invoke(bean, args);
// 方法之后执行
System.out.println("invoke after ...:"+result.toString());
}
// 执行方法 返回结果
return result;
}
});
return proxyInstance;
}
return bean;
}
}

最后执行userSerie.test(),aop拦截结果如下

================

详情源码看这个大神写的

https://www.cnblogs.com/liuyk-code/p/9886033.html

spring源码手写aop的更多相关文章

  1. Spring源码分析之AOP从解析到调用

    正文: 在上一篇,我们对IOC核心部分流程已经分析完毕,相信小伙伴们有所收获,从这一篇开始,我们将会踏上新的旅程,即Spring的另一核心:AOP! 首先,为了让大家能更有效的理解AOP,先带大家过一 ...

  2. Spring源码情操陶冶-AOP之Advice通知类解析与使用

    阅读本文请先稍微浏览下上篇文章Spring源码情操陶冶-AOP之ConfigBeanDefinitionParser解析器,本文则对aop模式的通知类作简单的分析 入口 根据前文讲解,我们知道通知类的 ...

  3. spring源码分析(二)Aop

    创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...

  4. Spring源码情操陶冶-AOP之ConfigBeanDefinitionParser解析器

    aop-Aspect Oriented Programming,面向切面编程.根据百度百科的解释,其通过预编译方式和运行期动态代理实现程序功能的一种技术.主要目的是为了程序间的解耦,常用于日志记录.事 ...

  5. spring源码学习之AOP(二)

    接着上一篇中的内容! 3.创建代理 在获取了所有的bean对应的增强器之后,便可以进行代理的创建了org.springframework.aop.framework.autoproxy包下的Abstr ...

  6. 【Spring源码分析】AOP源码解析(上篇)

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

  7. spring源码解析之AOP原理

    一.准备工作 在这里我先简单记录下如何实现一个aop: AOP:[动态代理] 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式: 1.导入aop模块:Spring AOP:(s ...

  8. spring源码系列8:AOP源码解析之代理的创建

    回顾 首先回顾: JDK动态代理与CGLIB动态代理 Spring中的InstantiationAwareBeanPostProcessor和BeanPostProcessor的区别 我们得知 JDK ...

  9. Spring源码分析之AOP

    1.AOP简介 AOP即面向切面编程(Aspect Oriented Programming),通过预编译方式及运行期动态代理实现程序功能的统一维护的一种技术.使用aop对业务逻辑的各个部分进行隔离, ...

  10. 史上最完整promise源码手写实现

    史上最完整的promise源码实现,哈哈,之所以用这个标题,是因为开始用的标题<手写promise源码>不被收录 promise自我介绍 promise : "君子一诺千金,承诺 ...

随机推荐

  1. Git的使用(二):远程仓库

    在github上创建远程仓库 本地创建Git仓库适合自己一个人完成工程,但是实际情况中我们需要其他人来协作开发,此时就可以把本地仓库同步到远程仓库,同时还增加了本地仓库的一个备份.常用的远程仓库就是g ...

  2. SqlSugar子查询

    1.基础教程 1.1 API目录 *****只查一列***** //First: SqlFunc.Subqueryable<School>().Where(s => s.Id ==  ...

  3. 如何在Visual Studio新C++项目中调用之前配置过的库?

      本文介绍在Visual Studio软件中调用C++各种配置.编译完毕的第三方库的方法.   在撰写C++代码时,如果需要用到他人撰写的第三方库(例如地理数据处理库GDAL.矩阵运算库Armadi ...

  4. static_cast, dynamic_cast与reinterpret_cast的区别

    在C++中,static_cast, dynamic_cast和reinterpret_cast都可用于类型转换,它们在具体使用时有什么区别?此外,更为重要的是,为什么不推荐使用强制类型转换? 1. ...

  5. AOF

    AOF 基础概念 以日志的形式记录了每个写操作 在redis重新运行时,会将这些操作重新执行一遍 文件形式:appendonly.aof 开启AOF需要更改配置文件:appendonly:yes AO ...

  6. Adoquery 简单的事务 编程 超级棒

    1.记得 有一次 看 c#视频教程,发现了一个简单事务 处理的绝佳方法,就是 adoquery 其实是可以 同时执行多条 SQL 语句的, 当其中一条 SQL 语句失败了,那么其余 SQL 语句也会失 ...

  7. AT_abc270_g [ABC270G] Sequence in mod P 题解

    题目传送门 前置知识 大步小步算法 解法 递推式为 \(x_{n}=(ax_{n-1}+b) \bmod p\),发现可以统一消去 \(\bmod p\) ,只在最后参与计算.以下过程省去模运算. 当 ...

  8. SP16113 SUBTLEBA - Trucks Transportation 题解

    题目传送门 前言 本题样例有问题,如果想要样例可以去 vjudge 上. 本题提交后可能会出现 UKE ,建议前往 link 提交,而且本篇题解中所提供的代码也为 link 代码. 前置知识 Krus ...

  9. NC15445 wyh的吃鸡

    题目链接 题目 题目描述 最近吃鸡游戏非常火,你们wyh学长也在玩这款游戏,这款游戏有一个非常重要的过程,就是要跑到安全区内,否则就会中毒持续消耗血量,我们这个问题简化如下 假设地图为n*n的一个图, ...

  10. SSD接口与协议

    该图来源于<Linux开源存储全栈详解:从Ceph到容器存储>- 2.3 存储接口协议的演变 物理接口: 从物理形态上确定各种不同的接口(引脚形式等完全不同) 传输协议: 以SATA为例, ...