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. Flask四剑客

    目录 Flask四剑客 Flask四剑客 ''' 响应字符串 响应html页面 跳转页面 返回json字符串 ''' from flask import Flask, render_template, ...

  2. Sqlite管理工具

    ! https://zhuanlan.zhihu.com/p/375188242 SQLiteStudio 开源免费的一款sqlite数据库管理软件,支持windows,linux,macos 官网: ...

  3. @RequestBody中使用@DateTimeFormat报错:JSON parse error: Expected array or string.; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException

    原因分析 根据异常提示:不匹配输入异常,指输入的参数错误,说是只支持String类型和Array数组类型的. @PostMapping("/test") public Dto ge ...

  4. 图学习初探Paddle Graph Learning 构建属于自己的图【系列三】

    项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5000517?contributionType=1 如遇到问题查看原项目解决 图学习温故 ...

  5. 最新力作,爱来自rand函数

    AWCU47EF;D5F]ET[a8a9K6G5IRHB6RS\cD8YDC:AGN<Z@6ZI3ab8D3O3La7:Sc;5_B]BS5S6Q]baWGcTE94IX7cW=9F>BJ ...

  6. M2版Mac mini被京东杀到史低2888元!比苹果官网低1600

    苹果跳水王M2版Mac mini又降价了. 根据京东官方百亿补贴频道显示,Mac mini 8+256GB入门版只要2888元了,比前不久的拼多多2959还低,刷新了这款电脑的史上最低价. 对比官网原 ...

  7. curl接口调用

    CURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.最爽的是,PHP也支持 CURL 库.使用PHP的CURL 库可以简单和有效地去抓网页.你只 ...

  8. Go语言的100个错误使用场景(21-29)|数据类型

    目录 前言 3. Data types 3.5 低效的切片初始化(#21) 3.6 切片为 nil 与为空混淆(#22) 3.7 没有正确检查切片是否为空(#23) 3.8 错误的切片拷贝(#24) ...

  9. Oracle-ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

    问题描述 ORA-12505, TNS:listener does not currently know of SID given in connect descriptorORA-12505: TN ...

  10. NC20875 舔狗舔到最后一无所有

    题目链接 题目 题目描述 作为队伍的核心,forever97很受另外两个队友的尊敬. Trote_w每天都要请forever97吃外卖,但很不幸的是宇宙中心forever97所在的学校周围只有3家fo ...