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

做词云的网站网站建设医药

做词云的网站,网站建设医药,网站改版 内容,做网站业务对Spring AOP的理解 OOP表示面向对象编程,是一种编程思想,AOP表示面向切面编程,也是一种编程思想 Spring AOP:Spring为了让程序员更加方便的做到面向切面编程所提供的技术支持 Spring提供的一套机制,让我们更容易的…

对Spring AOP的理解

OOP表示面向对象编程,是一种编程思想,AOP表示面向切面编程,也是一种编程思想

Spring AOP:Spring为了让程序员更加方便的做到面向切面编程所提供的技术支持

Spring提供的一套机制,让我们更容易的进行AOP,这套机制就是Spring AOP

扩展:用注解的方式来定义Pointcut和Advice,Spring并不是首创,首创是 AspectJ。JBoss 4.0、aspectwerkz 等技术也提供了对于AOP的支持。

Spring是依赖了AspectJ的,Spring觉得AspectJ中的@Before、@Around等注解比较好用,所以把这些注解直接拿过来用,但是注解底层的解析是由Spring自己做的。

所以我们在用 Spring时,如果你想用@Before、@Around等注解,是需要单独引入aspecj相关jar包的:

compile group: 'org.aspectj', name: 'aspectjrt', version: '1.9.5'
compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.5'

注意:AspectJ(它自己也是一个项目)是在编译时对字节码进行了修改,可以理解为是在编译时就会去解析@Before这些注解,然后得到代理逻辑,加入到被代理类的字节码中去,所以如果想用AspectJ技术来生成代理对象 ,是需要用单独的AspectJ编译器的。项目中很少用AspectJ编译器,只是用了@Before这些注解,在启动Spring的过程中会去解析这些注解,然后利用动态代理机制生成代理对象。

AOP中的概念

Spring官网:

Let us begin by defining some central AOP concepts and terminology. These terms are not Spring-specific. Unfortunately, AOP terminology is not particularly intuitive. However, it would be even more confusing if Spring used its own terminology

翻译:AOP中的这些概念不是Spring特有的,不幸的是,AOP中的概念不是特别直观的,但是,如果Spring重新定义自己的那可能会导致更加混乱

1、Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等

2、Join point:表示连接点,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个连接点通常表示一个方法的执行

3、Advice:表示通知,表示在一个特定连接点上所采取的动作。很多AOP框架中,包括Spring,会用Interceptor拦截器来实现Advice,并且在连接点周围维护一个Interceptor链

4、Pointcut:表示切点,用来匹配一个或多个连接点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式所匹配的连接点上

5、Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口,并指定一个默认实现

6、Target object:目标对象,被代理对象

7、AOP proxy:表示代理工厂,用来创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理

8、Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如Aspejctj),或者运行时,比如Spring AOP

Advice在Spring AOP中对应的API

Aspject中用五个注解来定义Advice,表示代理逻辑,以及执行时机;Spring有提供类似执行时机的实现类:

Aspject注解(代理逻辑、执行时机)Spring实现类(类似执行时机)Spring解析注解为对应的Advice类
@Before接口MethodBeforeAdvice, 继承了接口BeforeAdviceAspectJMethodBeforeAdvice(实际上是MethodBeforeAdvice)
@AfterReturning接口AfterReturningAdviceAspectJAfterReturningAdvice(实际上是AfterReturningAdvice)
@AfterThrowing接口ThrowsAdviceAspectJAfterThrowingAdvice(实际上是MethodInterceptor)
@After接口AfterAdviceAspectJAfterAdvice(实际上是MethodInterceptor)
@Around接口MethodInterceptorAspectJAroundAdvice(实际上是MethodInterceptor)

TargetSource的使用

日常的AOP中,被代理对象就是Bean对象,是由BeanFactory创建出来的。

Spring AOP中提供了TargetSource机制,可以用自定义逻辑来创建被代理对象。

@Lazy注解当加在属性上时,会产生一个代理对象赋值给这个属性:

/*** Complete implementation of the* {@link org.springframework.beans.factory.support.AutowireCandidateResolver} strategy* interface, providing support for qualifier annotations as well as for lazy resolution* driven by the {@link Lazy} annotation in the {@code context.annotation} package.** @author Juergen Hoeller* @since 4.0*/
public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {@Override@Nullablepublic Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {// 判断是不是懒注入(@Autowired+@Lazy)// 如果是则会在注入时生成一个代理对象注入给属性,所以懒注入并不代表属性为nullreturn (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);}protected boolean isLazy(DependencyDescriptor descriptor) {for (Annotation ann : descriptor.getAnnotations()) {Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);if (lazy != null && lazy.value()) {return true;}}MethodParameter methodParam = descriptor.getMethodParameter();if (methodParam != null) {Method method = methodParam.getMethod();if (method == null || void.class == method.getReturnType()) {Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);if (lazy != null && lazy.value()) {return true;}}}return false;}protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {BeanFactory beanFactory = getBeanFactory();Assert.state(beanFactory instanceof DefaultListableBeanFactory,"BeanFactory needs to be a DefaultListableBeanFactory");final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;TargetSource ts = new TargetSource() {@Overridepublic Class<?> getTargetClass() {return descriptor.getDependencyType();}@Overridepublic boolean isStatic() {return false;}@Overridepublic Object getTarget() {Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<>(1) : null);Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);if (target == null) {Class<?> type = getTargetClass();if (Map.class == type) {return Collections.emptyMap();}else if (List.class == type) {return Collections.emptyList();}else if (Set.class == type || Collection.class == type) {return Collections.emptySet();}throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),"Optional dependency not present for lazy injection point");}if (autowiredBeanNames != null) {for (String autowiredBeanName : autowiredBeanNames) {if (dlbf.containsBean(autowiredBeanName)) {dlbf.registerDependentBean(autowiredBeanName, beanName);}}}return target;}@Overridepublic void releaseTarget(Object target) {}};// ProxyFactory生成代理对象,并使用了TargetSource// 所以代理对象在执行某个方法时,调用TargetSource的getTarget()方法实时得到一个被代理对象ProxyFactory pf = new ProxyFactory();pf.setTargetSource(ts);Class<?> dependencyType = descriptor.getDependencyType();if (dependencyType.isInterface()) {pf.addInterface(dependencyType);}return pf.getProxy(dlbf.getBeanClassLoader());}
}

Introduction(@DeclareParents)简介

Spring官网对Introduction和相关注解@DeclareParents的介绍:

Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on behalf of those objects. An introduction is made using the @DeclareParents annotation. This annotation is used to declare that matching types have a new parent (hence the name).

Introduction有什么用呢?

可以给一个已有的类引入新的接口,在不修改原类的情况下,做一些扩展行为

比如说生产上正在提供服务,这个时候想要加一个验证功能,就可以通过@DeclareParents注解实现

如何使用@DeclareParents注解?

// 第一步,添加一个接口
package com.gax.aop;
public interface Verifier
{boolean validate(User user);
}// 第二步,给接口添加一个实现类
package com.gax.aop;
public class BasicVerifier implements Verifier
{@Overridepublic boolean validate(User user){if (user.getName().equals("gc") && user.getPass().equals("6174")){return true;}return false;}
}// 第三步,使用@DeclareParents注解关联新增接口和原来的类
@Aspect
@Component
public class MyAspect
{@DeclareParents(value = "com.gax.service.UserService",defaultImpl = com.gax.aop.BasicVerifier.class)public Verifier verifer;
}// 第四步,测试效果
public class Test
{public static void main(String[] args){User user = new User();user.setPass("6174888");user.setName("gc");// 创建一个Spring容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = (UserService) applicationContext.getBean("userService");// 注意,这里Verifier是一个接口Verifier verifier = (Verifier) userService;// 验证通过才能提供服务if(verifier.validate(user)){userService.service();}}
}// AppConfig指定扫描包
@ComponentScan(value = "com.gax")
//@EnableAspectJAutoProxy
@Import(AnnotationAwareAspectJAutoProxyCreator.class)
public class AppConfig
{
}@Data
public class User
{private String name;private String pass;
}

@EnableAspectJAutoProxy

@Import(AnnotationAwareAspectJAutoProxyCreator.class)

某些情况下,上面这两种写法等价。@EnableAspectJAutoProxy注解内部其实就是注册了一个AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator其实就是一个BeanPostProcessor,在Spring启动过程中可以去解析AspectJ的注解

参考文章:https://www.cnblogs.com/powerwu/articles/5170861.html

LoadTimeWeaver

参考文章:https://www.cnblogs.com/davidwang456/p/5633609.html

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

相关文章:

  • 网站建设及推广费用接网站建设单子注意事项
  • 怎么在企业站建立网站带后台的网站模板下载
  • 佛山南海网站开发免费简历模板可导出
  • 中国建设银行的网站设计惠来县建设局网站
  • 网站建设典型发言元器件商城网站建设
  • nas做视频网站便宜点的网站建设
  • 网站的动态效果wordpress 去掉左上角
  • 淘宝联盟网站建设源码学习软件大全
  • 公司网站界面设计网站建设企业建站哪家好?来这里看看
  • 网站备案目的美的集团网站建设
  • 做的网站一定要收录么温州免费建站
  • 邵阳营销型网站三亚百度推广开户
  • 琳琅秀网站建设新品发布会朋友圈文案
  • 纯文字排版设计网站网站文件夹没有权限设置
  • 无锡网站制作推荐美术馆网站建设总体要求
  • 成都网站快照优化公司广州seo排名收费
  • 铜仁公司做网站成都网站建设赢展
  • 苏州专业建站wordpress段首空2字
  • 有什么可以接单做的网站北京百度推广
  • 桂林景区网站策划潍坊专职消防员
  • 服饰网站建设目的修改wordpress访问路径
  • 建设银行造价咨询中心网站青岛互联网设计公司
  • 十九冶成都建设有限公司网站百度竞价网站谁做
  • 优质院校建设网站英文网站建设设计
  • 网站前端设计秦皇岛黄金海岸门票多少钱
  • 网页设计制作网站html代码企业网站建
  • 常州免费网站建站模板wordpress仅显示标题
  • 网站开发产品需求说明企业的网站开发费用如何入账
  • 展示型网站有哪些网站标签图片修改
  • 鄂州网站建设推广报价淮南家政网站建设地址