>AOP基本概念

  1)通知(Advice):织入到目标类连接点上的一段程序代码。通知分为五种类型:

  - Before:在方法被调用之前调用

  - After:在方法完成后调用通知,无论方法是否执行成功

  - After-returning:在方法成功执行之后调用通知

  - After-throwing:在方法抛出异常后调用通知

  - Around:通知了好、包含了被通知的方法,在被通知的方法调用之前后调用之后执行自定义的行为

  2)切点(Pointcut):AOP通过“切点”定位特定的连接点

  3)连接点(Joinpoint):程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。这些代码中的特定点,称为“连接点”。

  4) 织入(Weaving):织入是将增强添加到目标类具体连接点上的过程。AOP有三种织入方式:

  - 编译期织入,这要求使用特殊的Java编译器;

  - 类装载期织入,这要求使用特殊的类装载器;

  - 动态代理织入,在运行期为目标类添加增强生成子类的方式。

  Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。

  5)切面(Aspect)切面由切点和通知组成,它既包括了横切逻辑的定义,也包括了连接点的定义

  Spring 是切片流程

  代理模式

  就好比明星和经纪人,经纪人负责接活,负责明星唱歌前会场准备,明星唱歌后收钱。 代理类其实就是在代理对象,前后做了一些其他的处理, 这已经具备 AOP的轮廓了

  静态代理模式栗子

  // 接口

  public interface IUserDao {

  void save();

  void find();

  }

  // 目标对象

  public class UserDao implements IUserDao {

  @Override

  public void save() {

  System.out.println("模拟:保存用户!");

  }

  @Override

  public void find() {

  System.out.println("模拟:查询用户");

  }

  }

  /**

  * 静态代理 特点:

  * 1. 目标对象必须要实现接口

  * 2. 代理对象,要实现与目标对象一样的接口

  */

  public class UserDaoProxy implements IUserDao {

  // 代理对象,需要维护一个目标对象

  private IUserDao target = new UserDao();

  @Override

  public void save() {

  System.out.println("代理操作: 开启事务...");

  target.save(); // 执行目标对象的方法

  System.out.println("代理操作:提交事务...");

  }

  @Override

  public void find() {

  target.find();

  }

  }

  public class StaticProxyTest {

  /**

  * @param args

  */

  public static void main(String[] args) {

  IUserDao proxy = new UserDaoProxy();

  proxy.save();

  }

  }

  可以看到,静态代理是必须要有接口的,代理类和目标类都得事先接口,这样就显得很麻烦了,每次代理一个目标对象,就得做一个代理类,有没有一种方式,可以使用一个代理 ,代理多个目标对象呢?

  动态代理模式栗子

  动态代理不需要提前建立代理,而是在运行时,为目标对象动态生成代理类

  // 接口

  public interface IUserDao {

  void save();

  void find();

  }

  // 目标对象

  public class UserDao implements IUserDao {

  @Override

  public void save() {

  System.out.println("模拟: 保存用户!");

  }

  @Override

  public void find() {

  System.out.println("查询");

  }

  }

  /**

  * 动态代理:JDK 动态代理采用的是反射机制实现

  * 代理工厂,给多个目标对象生成代理对象!

  *

  */

  public class ProxyFactory {

  // 接收一个目标对象

  private Object target;

  public ProxyFactory(Object target) {

  this.target = target;

  }

  // 返回对目标对象(target)代理后的对象(proxy)

  public Object getProxyInstance() {

  Object proxy = Proxy.newProxyInstance(

  target.getClass().getClassLoader(), // 目标对象使用的类加载器

  target.getClass().getInterfaces(), // 目标对象实现的所有接口

  new InvocationHandler() { // 执行代理对象方法时候触发

  @Override

  public Object invoke(Object proxy, Method method, Object[] args)

  throws Throwable {

  // 获取当前执行的方法的方法名

  String methodName = method.getName();

  // 方法返回值

  Object result = null;

  if ("find".equals(methodName)) {

  // 直接调用目标对象方法

  result = method.invoke(target, args);

  } else {

  System.out.println("开启事务...");

  // 执行目标对象方法

  result = method.invoke(target, args);

  System.out.println("提交事务...");

  }

  return result;

  }

  }

  );

  return proxy;

  }

  }

  public class JDKDynamicProxyTest {

  /**

  * @param args

  */

  public static void main(String[] args) {

  // 目标对象

  IUserDao target = new UserDao();

  // 创建代理类

  IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();

  System.out.println("代理对象: "+proxy.getClass());

  proxy.save();

  }

  }

  静态代理动态代理总结

  可以总结一下,JDK 动态代理

  // 创建代理类

  IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();

  实际上 隐藏了动态的去实现 目标对象的一个接口

  class $jdkProxy implements IUserDao{}

  也就是说 使用JDK 反射方式实现动态代理,目标对象必须实现一个接口,这就可能出现问题了,假设一个类,就是没有实现接口怎么办?

  CGLIB实现动态代理实现栗子

  CGLIB是使用继承的方式动态生成代理类,这个代理类是继承目标类的,这个就有个问题,需要目标类不被final修饰。

  有点类似

  public class UserDao{}

  // CGLIB 是以动态生成的子类继承目标的方式实现,程序执行时,隐藏了下面的过程

  public class $Cglib_Proxy_class extends UserDao{}

  CGLIB实现

  // 目标对象

  public class UserDao {

  public void save() {

  System.out.println("模拟: 保存用户!");

  }

  public void find() {

  System.out.println("查询");

  }

  }

  public class CGLIBProxyFactory {

  static class SimpleInterceptor implements MethodInterceptor {

  /**

  * @see org.springframework.cglib.proxy.MethodInterceptor#intercept(java.lang.Object,

  * java.lang.reflect.Method, java.lang.Object[],

  * org.springframework.cglib.proxy.MethodProxy)

  */

  @Override

  public Object intercept(Object target, Method methmod, Object[] args, MethodProxy proxy) throws Throwable {

  System.out.println("entering " + methmod.getName());

  Object result = proxy.invokeSuper(target, args);

  System.out.println("leveaing " + methmod.getName());

  return result;

  }

  }

  public static T getProxy(Class cls) {

  Enhancer enhancer = new Enhancer();

  // 继承目标类

  enhancer.setSuperclass(cls);

  enhancer.setCallback(new SimpleInterceptor());

  return (T) enhancer.create();

  }

  }

  public class CGLIBProxyTest {

  public static void main(String[] args) {

  //生成代理 没有接口

  UserDao proxy = (UserDao) CGLIBProxyFactory.getProxy(UserDao.class);

  System.out.println("代理类:"+ proxy.getClass());

  proxy.save();

  }

  }无锡正规妇科医院 http://www.jlfukeyy.com/

  JDK和CGLIB的区别

  1.上面可以可以看到 CGLIB是不需要 目标对象实现接口的, CGLIB是通过继承来实现的

  2. JDK动态代理是需要一个具体的目标对象的,但是CGLIB是不需要这么一个具体对象的

  Spring AOP 是怎样实现的呢?

  1.AOP 是基于动态代理模式

  2.AOP是方法级别的

  3.AOP可以分类业务代码和关注点代码(日志,事务等)

  AOP 是什么时候生成代理的?

  AOP 代理主要分为静态代理和动态代理两大类,静态代理以 AspectJ 为代表;而动态代理则以 Spring AOP 为代表

  IOC容器BeanDefinitionMap里面结构看内容是啥

  bean: class [org.springframework.aop.aspectj.AspectJPointcutAdvisor];

  scope=;

  abstract=false;

  lazyInit=false;

  autowireMode=0;

  dependencyCheck=0;

  autowireCandidate=true;

  primary=false;

  factoryBeanName=null;

  factoryMethodName=null;

  initMethodName=null;

  destroyMethodName=null,

  org.springframework.aop.aspectj.AspectJPointcutAdvisor#2=Root

  bean: class [org.springframework.aop.aspectj.AspectJPointcutAdvisor];

  scope=;

  abstract=false;

  lazyInit=false;

  autowireMode=0;

  dependencyCheck=0;

  autowireCandidate=true;

  primary=false;

  factoryBeanName=null;

  factoryMethodName=null;

  initMethodName=null;

  destroyMethodName=null,

  org.springframework.aop.aspectj.AspectJPointcutAdvisor#3=Root

  bean:class [org.springframework.aop.aspectj.AspectJPointcutAdvisor];

  scope=;

  abstract=false;

  lazyInit=false;

  autowireMode=0;

  dependencyCheck=0;

  autowireCandidate=true;

  primary=false;

  factoryBeanName=null;

  factoryMethodName=null;

  initMethodName=null;

  destroyMethodName=null,

  org.springframework.aop.aspectj.AspectJPointcutAdvisor#0=Root

Spring AOP 原理的理解的更多相关文章

  1. 面试问烂的 Spring AOP 原理、SpringMVC 过程(求求你别问了)

    Spring AOP ,SpringMVC ,这两个应该是国内面试必问题,网上有很多答案,其实背背就可以.但今天笔者带大家一起深入浅出源码,看看他的原理.以期让印象更加深刻,面试的时候游刃有余. Sp ...

  2. Spring学习总结(1)——Spring AOP的概念理解

    1.我所知道的aop 初看aop,上来就是一大堆术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下子让你不知所措,心想着:怪不得 很多人都和我说aop多难多难 .当我看进去 ...

  3. spring aop原理分析

    持续更新... aop跟java代理模式有关. java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 工厂模式用到java反射. ao ...

  4. aop原理及理解

    概念 Aspect Oriented Programming,面向切面编程,实际上它是一个规范.一种设计思路,总之是抽象的. 先上图 使用目的 从项目结构上来说 对业务逻辑的各个部分进行隔离,降低业务 ...

  5. Spring AOP原理(续)

    十二.AOP 1. 说出Spring的通知类型有哪些? spring共提供了五种类型的通知: 通知类型 接口 描述 Around 环绕通知 org.aopalliance.intercept.Meth ...

  6. Spring Boot -- Spring AOP原理及简单实现

    一.AOP基本概念 什么是AOP,AOP英语全名就是Aspect oriented programming,字面意思就是面向切面编程.面向切面的编程是对面向对象编程的补充,面向对象的编程核心模块是类, ...

  7. spring ioc 原理 spring aop原理

    大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC其实也非常的简单.我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对 ...

  8. spring aop 原理学习

    @EnableAspectJAutoProxy: @Import(AspectJAutoProxyRegistrar.class) 实际是创建了一个以org.springframework.aop.c ...

  9. spring aop原理和实现

    一.aop是什么 1.AOP面向方面编程基于IoC,是对OOP的有益补充: 2.AOP利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了 多个类的公共行为封装到一个可 ...

随机推荐

  1. NodeJS包管理器之Yarn

    一.安装yarn 首选必须先安装好NodeJS,之后可以去yarn官网下载mis安装程序安装.由于NodeJS自带了一个包管理器npm,所以安装yarn更简单的方法是直接使用npm install - ...

  2. Feign进行文件上传+表单调用

    Feigin默认是不支持文件上传和表单提交的,需要做一些配置才能支持. 1.feign依赖 图中红色为form支持必须的jar. 2.添加自定义Encoder类: import static java ...

  3. Spring不能直接@autowired注入Static变量/ 关于SpringBoot的@Autowired 静态变量注入

    昨天在编写JavaMail工具类的时候,静态方法调用静态变量,这是很正常的操作,当时也没多想,直接静态注入. @Component public class JavaMailUtil { @Autow ...

  4. Mac OSX系统中Hadoop / Hive 与 spark 的安装与配置 环境搭建 记录

    Mac OSX系统中Hadoop / Hive 与 spark 的安装与配置 环境搭建 记录     Hadoop 2.6 的安装与配置(伪分布式) 下载并解压缩 配置 .bash_profile : ...

  5. SpringBoot 上下文获取注入的Bean

    import org.springframework.beans.BeansException; import org.springframework.context.ApplicationConte ...

  6. 百度URL参数解析

    在用Python爬取百度搜索的内容时,发现百度搜索的url非常的长,往往会跟一大段的参数,但其实很多参数都是没有必要的,如同样是搜索java关键字,可以通过 http://www.baidu.com/ ...

  7. zabbix 后台数据库清除数据

    alerts 表 problem 表 escalations 表 events 表  event_recovery表 对 这些表进行清除 防止不停发送邮件 -- alerts table rebuil ...

  8. Content-type"是"application/json的作用

    request中发送json数据用post方式发送Content-type用application/json;charset=utf-8方式发送的话,直接用springMVC的@RequestBody ...

  9. PHP 跨域资源共享 CORS 设定

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  10. 【转帖】Intel AMD 龙芯2019年12月份最新产品线

    Intel未来三代U集体曝光:14nm退回去了! https://news.cnblogs.com/n/651244/ 不过没搞懂 为啥中芯国际已经开始量产14nm了 龙芯为什么不用.. 3A4000 ...