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

有网站和无网站的区别网站型跟商城型

有网站和无网站的区别,网站型跟商城型,wordpress 502错误,建网站程序怎么写问题复现 假设我们正在开发一个宿舍管理系统#xff0c;这个模块包含一个负责电费充值的类 ElectricService#xff0c;它含有一个充电方法 charge()#xff1a; Service public class ElectricService {public void charge() throws Exception {System.out.println(E…问题复现 假设我们正在开发一个宿舍管理系统这个模块包含一个负责电费充值的类 ElectricService它含有一个充电方法 charge() Service public class ElectricService {public void charge() throws Exception {System.out.println(Electric charging ...);this.pay();}public void pay() throws Exception {System.out.println(Pay with alipay ...);Thread.sleep(1000);}}在这个电费充值方法 charge() 中我们会使用支付宝进行充值。因此在这个方法中我加入了 pay() 方法。为了模拟 pay() 方法调用耗时代码执行了休眠 1 秒并在 charge() 方法里使用 this.pay() 的方式调用这种支付方法。 但是因为支付宝支付是第三方接口我们需要记录下接口调用时间。这时候我们就引入了一个 Around 的增强 分别记录在 pay() 方法执行前后的时间并计算出执行 pay() 方法的耗时。 Aspect Service Slf4j public class AopConfig {Around(execution(* com.spring.puzzle.class5.example1.ElectricService.pay()) )public void recordPayPerformance(ProceedingJoinPoint joinPoint) throws Throwable {long start System.currentTimeMillis();joinPoint.proceed();long end System.currentTimeMillis();System.out.println(Pay method time costms: (end - start));} }最后我们再通过定义一个 Controller 来提供电费充值接口定义如下 RestController public class HelloWorldController {AutowiredElectricService electricService;RequestMapping(path charge, method RequestMethod.GET)public void charge() throws Exception{electricService.charge();}; }完成代码后我们访问上述接口会发现这段计算时间的切面并没有执行到输出日志如下 Electric charging ... Pay with alipay ...回溯之前的代码可知在 Around 的切面类中我们很清晰地定义了切面对应的方法但是却没有被执行到。这说明了在类的内部通过 this 方式调用的方法是没有被 Spring AOP 增强的。这是为什么呢我们来分析一下。 案例解析 我们可以从源码中找到真相。首先来设置个断点调试看看 this 对应的对象是什么样的 可以看到this 对应的就是一个普通的 ElectricService 对象并没有什么特别的地方。再看看在 Controller 层中自动装配的 ElectricService 对象是什么样 可以看到这是一个被 Spring 增强过的 Bean所以执行 charge() 方法时会执行记录接口调用时间的增强操作。而 this 对应的对象只是一个普通的对象并没有做任何额外的增强。为什么 this 引用的对象只是一个普通对象呢这还要从 Spring AOP 增强对象的过程来看。但在此之前有些基础我需要在这里强调下。 1. Spring AOP 的实现 Spring AOP 的底层是动态代理。而创建代理的方式有两种JDK 的方式和 CGLIB 的方式。JDK 动态代理只能对实现了接口的类生成代理而不能针对普通类。而 CGLIB 是可以针对类实现代理主要是对指定的类生成一个子类覆盖其中的方法来实现代理对象。具体区别可参考下图 2. 如何使用 Spring AOP 在 Spring Boot 中我们一般只要添加以下依赖就可以直接使用 AOP 功能 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId /dependency而对于非 Spring Boot 程序除了添加相关 AOP 依赖项外我们还常常会使用 EnableAspectJAutoProxy 来开启 AOP 功能。这个注解类引入ImportAspectJAutoProxyRegistrar它通过实现 ImportBeanDefinitionRegistrar 的接口方法来完成 AOP 相关 Bean 的准备工作。 补充完最基本的 Spring 底层知识和使用知识后我们具体看下创建代理对象的过程。先来看下调用栈 创建代理对象的时机就是创建一个 Bean 的时候而创建的的关键工作其实是由 AnnotationAwareAspectJAutoProxyCreator 完成的。它本质上是一种 BeanPostProcessor。所以它的执行是在完成原始 Bean 构建后的初始化 BeaninitializeBean过程中。而它到底完成了什么工作呢我们可以看下它的 postProcessAfterInitialization 方法 public Object postProcessAfterInitialization(Nullable Object bean, String beanName) {if (bean ! null) {Object cacheKey getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) ! bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean; }上述代码中的关键方法是 wrapIfNecessary顾名思义在需要使用 AOP 时它会把创建的原始的 Bean 对象 wrap 成代理对象作为 Bean 返回。具体到这个 wrap 过程可参考下面的关键代码行 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// 省略非关键代码Object[] specificInterceptors getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors ! DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);Object proxy createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}// 省略非关键代码 }上述代码中第 6 行的 createProxy 调用是创建代理对象的关键。具体到执行过程它首先会创建一个代理工厂然后将通知器advisors、被代理对象等信息加入到代理工厂最后通过这个代理工厂来获取代理对象。一些关键过程参考下面的方法 protected Object createProxy(Class? beanClass, Nullable String beanName,Nullable Object[] specificInterceptors, TargetSource targetSource) {// 省略非关键代码ProxyFactory proxyFactory new ProxyFactory();if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}Advisor[] advisors buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);// 省略非关键代码return proxyFactory.getProxy(getProxyClassLoader()); }经过这样一个过程一个代理对象就被创建出来了。我们从 Spring 中获取到的对象都是这个代理对象所以具有 AOP 功能。而之前直接使用 this 引用到的只是一个普通对象自然也就没办法实现 AOP 的功能了。 问题修正 从上述案例解析中我们知道只有引用的是被动态代理创建出来的对象才会被 Spring 增强具备 AOP 该有的功能。那什么样的对象具备这样的条件呢有两种。一种是被 Autowired 注解的于是我们的代码可以改成这样即通过 Autowired 的方式在类的内部自己引用自己Service public class ElectricService {AutowiredElectricService electricService;public void charge() throws Exception {System.out.println(Electric charging ...);//this.pay();electricService.pay();}public void pay() throws Exception {System.out.println(Pay with alipay ...);Thread.sleep(1000);} }另一种方法就是直接从 AopContext 获取当前的 Proxy。那你可能会问了AopContext 是什么简单说它的核心就是通过一个 ThreadLocal 来将 Proxy 和线程绑定起来这样就可以随时拿出当前线程绑定的 Proxy。不过使用这种方法有个小前提就是需要在 EnableAspectJAutoProxy 里加一个配置项 exposeProxy true表示将代理对象放入到 ThreadLocal这样才可以直接通过 AopContext.currentProxy() 的方式获取到否则会报错如下 按这个思路我们修改下相关代码import org.springframework.aop.framework.AopContext; import org.springframework.stereotype.Service; Service public class ElectricService {public void charge() throws Exception {System.out.println(Electric charging ...);ElectricService electric ((ElectricService) AopContext.currentProxy());electric.pay();}public void pay() throws Exception {System.out.println(Pay with alipay ...);Thread.sleep(1000);} }同时不要忘记修改 EnableAspectJAutoProxy 注解的 exposeProxy 属性示例如下SpringBootApplication EnableAspectJAutoProxy(exposeProxy true) public class Application {// 省略非关键代码 }这两种方法的效果其实是一样的最终我们打印出了期待的日志到这问题顺利解决了。Electric charging ... Pay with alipay ... Pay method time cost(ms): 1005
http://www.hkea.cn/news/14351868/

相关文章:

  • 什么是做自己的网站网站开发的著作权和版权
  • 国外视觉差网站企业策划书
  • 怎样做天猫 淘宝网站导购有趣的网站名
  • 国外网站做营销外贸网站代运营
  • 做网站大记事代码ie显示wordpress网页不完整
  • 广州软件园 网站建设jquery 开发网站
  • 网站建站网站山东广饶县建设局网站
  • 百度站长推送欧美化妆品网站模板下载
  • wordpress建站dedecms站长论坛 激活网站
  • 做超市促销海报哪个网站好凡科手机网站建设
  • 网站弄论坛形式怎么做建设银行苏州网站
  • 建设校园标准信息服务网站论文东营房产信息网58同城
  • 交流网站模版婚纱网站有哪些
  • 重庆自助模板建站行业网站策划
  • 网站风格有哪些淮北建网站费用
  • 做名片网站短期网站建设培训班
  • 莱州网站建设政法队伍建设网站主要内容
  • 网站建设宣传视频2022麻豆区区区三区四区
  • 安仁做网站东莞长安网站优化公司
  • 收费图片网站不买服务器做网站
  • 建立网站要钱吗企业做网站系统
  • 惠州品牌网站建设价格品牌网图片新闻2003年下一条文章
  • 怎样用自己的主机做网站wordpress调用用户头像
  • 苏州做网站设计的公司网站建设比较好的
  • 网站快照查询sem专员
  • 邵阳优秀网站建设线在科技成都网站推广公司
  • 网站设计制作报告平面设计专业学校排名
  • server 2008 iis 部署网站地方门户源码
  • 为什么公司网站打不开环球新军事最新消息
  • 六安市裕安区建设局网站下载wordpress 4.8.1