| @Lazy一般含义是懒加载,它只会作用于BeanDefinition.setLazyInit()。而此处给它增加了一个能力:延迟处理(代理处理)
 // @since 4.0 出现得挺晚,它支持到了@Lazy  是功能最全的AutowireCandidateResolver     public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {         // 这是此类本身唯一做的事,此处精析          // 返回该 lazy proxy 表示延迟初始化,实现过程是查看在 @Autowired 注解处是否使用了 @Lazy = true 注解          @Override         @Nullable         public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {             // 如果isLazy=true  那就返回一个代理,否则返回null             // 相当于若标注了@Lazy注解,就会返回一个代理(当然@Lazy注解的value值不能是false)             return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);         }              // 这个比较简单,@Lazy注解标注了就行(value属性默认值是true)         // @Lazy支持标注在属性上和方法入参上~~~  这里都会解析         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) {             Assert.state(getBeanFactory() instanceof DefaultListableBeanFactory,                     "BeanFactory needs to be a DefaultListableBeanFactory");                  // 这里毫不客气的使用了面向实现类编程,使用了DefaultListableBeanFactory.doResolveDependency()方法~~~             final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();                  //TargetSource 是它实现懒加载的核心原因,在AOP那一章节了重点提到过这个接口,此处不再叙述             // 它有很多的著名实现如HotSwappableTargetSource、SingletonTargetSource、LazyInitTargetSource、             //SimpleBeanTargetSource、ThreadLocalTargetSource、PrototypeTargetSource等等非常多             // 此处因为只需要自己用,所以采用匿名内部类的方式实现~~~ 此处最重要是看getTarget方法,它在被使用的时候(也就是代理对象真正使用的时候执行~~~)             TargetSource ts = new TargetSource() {                 @Override                 public Class<?> getTargetClass() {                     return descriptor.getDependencyType();                 }                 @Override                 public boolean isStatic() {                     return false;                 }                          // getTarget是调用代理方法的时候会调用的,所以执行每个代理方法都会执行此方法,这也是为何doResolveDependency                 // 我个人认为它在效率上,是存在一定的问题的~~~所以此处建议尽量少用@Lazy~~~                    //不过效率上应该还好,对比http、序列化反序列化处理,简直不值一提  所以还是无所谓  用吧                 @Override                 public Object getTarget() {                     Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);                     if (target == null) {                         Class<?> type = getTargetClass();                         // 对多值注入的空值的友好处理(不要用null)                         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");                     }                     return target;                 }                 @Override                 public void releaseTarget(Object target) {                 }             };                     // 使用ProxyFactory  给ts生成一个代理             // 由此可见最终生成的代理对象的目标对象其实是TargetSource,而TargetSource的目标才是我们业务的对象             ProxyFactory pf = new ProxyFactory();             pf.setTargetSource(ts);             Class<?> dependencyType = descriptor.getDependencyType();                          // 如果注入的语句是这么写的private AInterface a;  那这类就是借口 值是true             // 把这个接口类型也得放进去(不然这个代理都不属于这个类型,反射set的时候岂不直接报错了吗????)             if (dependencyType.isInterface()) {                 pf.addInterface(dependencyType);             }             return pf.getProxy(beanFactory.getBeanClassLoader());         }     } 
 (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |