当前位置: 首页 > news >正文

信德 网站建设建筑设计网站模板

信德 网站建设,建筑设计网站模板,淘宝网站首页怎么做,统一开发平台大家都知道,AOP 底层是动态代理,而 Java 中的动态代理有两种实现方式: 基于 JDK 的动态代理 基于 Cglib 的动态代理 这两者最大的区别在于基于 JDK 的动态代理需要被代理的对象有接口,而基于 Cglib 的动态代理并不需要被代理对…

大家都知道,AOP 底层是动态代理,而 Java 中的动态代理有两种实现方式:

  • 基于 JDK 的动态代理

  • 基于 Cglib 的动态代理

这两者最大的区别在于基于 JDK 的动态代理需要被代理的对象有接口,而基于 Cglib 的动态代理并不需要被代理对象有接口。

那么,Spring 中的 AOP 是怎么实现的?是基于 JDK 的动态代理还是基于 Cglib 的动态代理?

1. Spring

先来说结论,Spring 中的动态代理,具体用哪种,分情况:

  • 如果代理对象有接口,就用 JDK 动态代理,否则就是 Cglib 动态代理。

  • 如果代理对象没有接口,那么就直接是 Cglib 动态代理。

来看看这段来自官方文档的说辞:

可以看到,即使在最新版的 Spring 中,依然是如上策略不变。即能用 JDK 做动态代理就用 JDK,不能用 JDK 做动态代理就用 Cglib,即首选 JDK 做动态代理。

2. Spring Boot 

Spring Boot 和 Spring 一脉相承,那么在动态代理这个问题上是否也是相同的策略呢?抱歉,这个还真不一样。

Spring Boot 中对这个问题的处理,以 Spring Boot2.0 为节点,前后不一样。

在 Spring Boot2.0 之前,关于 Aop 的自动化配置代码是这样的(Spring Boot 1.5.22.RELEASE):

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {@Configuration@EnableAspectJAutoProxy(proxyTargetClass = false)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",matchIfMissing = true)public static class JdkDynamicAutoProxyConfiguration {}@Configuration@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",matchIfMissing = false)public static class CglibAutoProxyConfiguration {}}

可以看到,这个自动化配置主要是在讨论 application.properties 配置文件中的 spring.aop.proxy-target-class 属性的值。

具体起作用的是 @ConditionalOnProperty 注解,关于这个注解中的几个属性,也来稍微说下:

  • prefix:配置文件的前缀。

  • name:配置文件的名字,和 prefix 共同组成配置的 key。

  • having:期待配置的值,如果实际的配置和 having 的值相同,则这个配置就会生效,否则不生效。

  • matchIfMissing:如果开发者没有在 application.properties 中进行配置,那么这个配置类是否生效。

基于如上介绍,很容易看出:

  • 如果开发者设置了 spring.aop.proxy-target-class 为 false,则使用 JDK 代理。

  • 如果开发者设置了 spring.aop.proxy-target-class 为 true,则使用 Cglib 代理。

  • 如果开发者一开始就没配置 spring.aop.proxy-target-class 属性,则使用 JDK 代理。

这是 Spring Boot 2.0 之前的情况。

再来看看 Spring Boot 2.0(含)之后的情况(Spring Boot 2.0.0.RELEASE):

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {@Configuration@EnableAspectJAutoProxy(proxyTargetClass = false)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)public static class JdkDynamicAutoProxyConfiguration {}@Configuration@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)public static class CglibAutoProxyConfiguration {}}

可以看到,大部分配置都是一样的,有一个地方不太相同,那就是 matchIfMissing 属性的值。可以看到,从 Spring Boot2.0 开始,如果用户什么都没有配置,那么默认情况下使用的是 Cglib 代理。

3. 实践

最后可以写一个简单的例子验证一下上面的理论。

首先创建一个 Spring Boot 项目(本案例使用最新版 Spring Boot,即默认使用 Cglib 代理),加入三个依赖即可,如下:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

接下来创建一个 IUserService 接口,如下:

public interface IUserService {void hello();}

然后再来创建一个该接口的实现类:

@Service
public class UserServiceImpl implements IUserService {@Overridepublic void hello() {}}

方法不用实现。

再来一个简单的切面:

@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspect {@Before("execution(* org.lzx.demo.UserServiceImpl.*(..))")public void before(JoinPoint jp) {System.out.println("jp.getSignature().getName() = " + jp.getSignature().getName());}}

最后再来一个简单的测试方法,注入 IUserService 实例:

@RestController
public class HelloController {@Autowiredprivate IUserService iUserService;@GetMapping("/hello")public void hello() {iUserService.hello();}}

DBUEG 运行一下,就可以看到 IUserService 是通过 Cglib 来代理的。

如果我们想用 JDK 来代理,那么只需要在 application.properties 中添加如下配置即可:

spring.aop.proxy-target-class=false

添加完成后,重新 DEBUG,如下图:

可以看到,已经使用了 JDK 动态代理了。

如果用的是 Spring Boot 1.5.22.RELEASE 这个版本,那么即使不在 application.properties 中添加配置,默认也是 JDK 代理。 

4. 小结

总结一下:

  1. Spring 中的 AOP,有接口就用 JDK 动态代理,没有接口就用 Cglib 动态代理。

  2. Spring Boot 中的 AOP,2.0 之前和 Spring 一样;2.0 之后首选 Cglib 动态代理,如果用户想要使用 JDK 动态代理,需要自己手动配置。

http://www.yayakq.cn/news/345879/

相关文章:

  • 网站后台无法编辑文字网页设计素材代码包
  • 如何创造免费网站松江网站建设博客
  • 卖链接的网站公众号涨粉平台
  • 注册网站需要什么手续成都有什么好玩的
  • 柳州集团学校网站建设手机软文广告300字
  • 在线手机动画网站模板下载安装简单炫酷的编程代码
  • 怎么做一款网站长沙口碑最好网站建设公司排行榜
  • 石家庄+网站建设wordpress如何自定义导航栏
  • 备案网址查询做网站需求 后期方便优化
  • 三门峡城乡建设局网站苏州网站建设 凡仕臣网络
  • 淮安企业网站制作做网站需要什么配置服务器吗
  • 南平网站怎么做seo网站工作沟通及建设
  • 企业做app好还是网站好企业管理工具
  • 网站设置不能手机访问单位网站建设做到哪个科目
  • 成都高端网站建设公司网上商城购物系统流程图
  • 在线制作图网站网站制作怎样做背景
  • 家居企业网站建设咨询wordpress在文章中加背景
  • 青海免费网站建设济宁做网站优化
  • 外贸网站模板推荐wordpress自动翻页
  • 店铺的网站怎么做网站模板免费吗
  • 5118网站怎么做的哔哩网站开发需求分析模板
  • 咸宁网站制作培训番禺本地网站
  • 网站关键词优化办法网站建设丶金手指花总11
  • php网站培训网上拿手工做的网站
  • 百度多久收录一次网站安贞网站建设公司
  • 中国建设银行投诉网站专门做宠物食品的网站
  • 新浪云怎么做自己的网站网站程序备份方法
  • 网站注册账号怎么做毕业设计做网站用什么软件
  • 木樨园网站建设珠海网站建设有限公司
  • 东莞的网站建设公司哪家好阿里云服务器 wordpress