@Resource injection points support @Lazy as well
Issue: SPR-12654
This commit is contained in:
parent
b94c6fdf7a
commit
e3d1a1dda2
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -44,6 +44,8 @@ import javax.xml.ws.Service;
|
||||||
import javax.xml.ws.WebServiceClient;
|
import javax.xml.ws.WebServiceClient;
|
||||||
import javax.xml.ws.WebServiceRef;
|
import javax.xml.ws.WebServiceRef;
|
||||||
|
|
||||||
|
import org.springframework.aop.TargetSource;
|
||||||
|
import org.springframework.aop.framework.ProxyFactory;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.PropertyValues;
|
import org.springframework.beans.PropertyValues;
|
||||||
|
|
@ -414,6 +416,44 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||||
return new InjectionMetadata(clazz, elements);
|
return new InjectionMetadata(clazz, elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a lazily resolving resource proxy for the given name and type,
|
||||||
|
* delegating to {@link #getResource} on demand once a method call comes in.
|
||||||
|
* @param element the descriptor for the annotated field/method
|
||||||
|
* @param requestingBeanName the name of the requesting bean
|
||||||
|
* @return the resource object (never {@code null})
|
||||||
|
* @since 4.2
|
||||||
|
* @see #getResource
|
||||||
|
* @see Lazy
|
||||||
|
*/
|
||||||
|
protected Object buildLazyResourceProxy(final LookupElement element, final String requestingBeanName) {
|
||||||
|
TargetSource ts = new TargetSource() {
|
||||||
|
@Override
|
||||||
|
public Class<?> getTargetClass() {
|
||||||
|
return element.lookupType;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isStatic() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Object getTarget() {
|
||||||
|
return getResource(element, requestingBeanName);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void releaseTarget(Object target) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ProxyFactory pf = new ProxyFactory();
|
||||||
|
pf.setTargetSource(ts);
|
||||||
|
if (element.lookupType.isInterface()) {
|
||||||
|
pf.addInterface(element.lookupType);
|
||||||
|
}
|
||||||
|
ClassLoader classLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||||
|
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() : null);
|
||||||
|
return pf.getProxy(classLoader);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the resource object for the given name and type.
|
* Obtain the resource object for the given name and type.
|
||||||
* @param element the descriptor for the annotated field/method
|
* @param element the descriptor for the annotated field/method
|
||||||
|
|
@ -527,6 +567,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||||
*/
|
*/
|
||||||
private class ResourceElement extends LookupElement {
|
private class ResourceElement extends LookupElement {
|
||||||
|
|
||||||
|
private final boolean lazyLookup;
|
||||||
|
|
||||||
public ResourceElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
|
public ResourceElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
|
||||||
super(member, pd);
|
super(member, pd);
|
||||||
Resource resource = ae.getAnnotation(Resource.class);
|
Resource resource = ae.getAnnotation(Resource.class);
|
||||||
|
|
@ -552,11 +594,14 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||||
this.name = resourceName;
|
this.name = resourceName;
|
||||||
this.lookupType = resourceType;
|
this.lookupType = resourceType;
|
||||||
this.mappedName = resource.mappedName();
|
this.mappedName = resource.mappedName();
|
||||||
|
Lazy lazy = ae.getAnnotation(Lazy.class);
|
||||||
|
this.lazyLookup = (lazy != null && lazy.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getResourceToInject(Object target, String requestingBeanName) {
|
protected Object getResourceToInject(Object target, String requestingBeanName) {
|
||||||
return getResource(this, requestingBeanName);
|
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
|
||||||
|
getResource(this, requestingBeanName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -437,6 +437,60 @@ public class CommonAnnotationBeanPostProcessorTests {
|
||||||
assertTrue(bean.destroy2Called);
|
assertTrue(bean.destroy2Called);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLazyResolutionWithResourceField() {
|
||||||
|
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||||
|
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
|
||||||
|
bpp.setBeanFactory(bf);
|
||||||
|
bf.addBeanPostProcessor(bpp);
|
||||||
|
|
||||||
|
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(LazyResourceFieldInjectionBean.class));
|
||||||
|
bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
|
||||||
|
|
||||||
|
LazyResourceFieldInjectionBean bean = (LazyResourceFieldInjectionBean) bf.getBean("annotatedBean");
|
||||||
|
assertFalse(bf.containsSingleton("testBean"));
|
||||||
|
bean.testBean.setName("notLazyAnymore");
|
||||||
|
assertTrue(bf.containsSingleton("testBean"));
|
||||||
|
TestBean tb = (TestBean) bf.getBean("testBean");
|
||||||
|
assertEquals("notLazyAnymore", tb.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLazyResolutionWithResourceMethod() {
|
||||||
|
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||||
|
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
|
||||||
|
bpp.setBeanFactory(bf);
|
||||||
|
bf.addBeanPostProcessor(bpp);
|
||||||
|
|
||||||
|
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(LazyResourceMethodInjectionBean.class));
|
||||||
|
bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
|
||||||
|
|
||||||
|
LazyResourceMethodInjectionBean bean = (LazyResourceMethodInjectionBean) bf.getBean("annotatedBean");
|
||||||
|
assertFalse(bf.containsSingleton("testBean"));
|
||||||
|
bean.testBean.setName("notLazyAnymore");
|
||||||
|
assertTrue(bf.containsSingleton("testBean"));
|
||||||
|
TestBean tb = (TestBean) bf.getBean("testBean");
|
||||||
|
assertEquals("notLazyAnymore", tb.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLazyResolutionWithCglibProxy() {
|
||||||
|
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||||
|
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
|
||||||
|
bpp.setBeanFactory(bf);
|
||||||
|
bf.addBeanPostProcessor(bpp);
|
||||||
|
|
||||||
|
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(LazyResourceCglibInjectionBean.class));
|
||||||
|
bf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
|
||||||
|
|
||||||
|
LazyResourceCglibInjectionBean bean = (LazyResourceCglibInjectionBean) bf.getBean("annotatedBean");
|
||||||
|
assertFalse(bf.containsSingleton("testBean"));
|
||||||
|
bean.testBean.setName("notLazyAnymore");
|
||||||
|
assertTrue(bf.containsSingleton("testBean"));
|
||||||
|
TestBean tb = (TestBean) bf.getBean("testBean");
|
||||||
|
assertEquals("notLazyAnymore", tb.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class AnnotatedInitDestroyBean {
|
public static class AnnotatedInitDestroyBean {
|
||||||
|
|
||||||
|
|
@ -716,6 +770,35 @@ public class CommonAnnotationBeanPostProcessorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class LazyResourceFieldInjectionBean {
|
||||||
|
|
||||||
|
@Resource @Lazy
|
||||||
|
private ITestBean testBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class LazyResourceMethodInjectionBean {
|
||||||
|
|
||||||
|
private ITestBean testBean;
|
||||||
|
|
||||||
|
@Resource @Lazy
|
||||||
|
public void setTestBean(ITestBean testBean) {
|
||||||
|
this.testBean = testBean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class LazyResourceCglibInjectionBean {
|
||||||
|
|
||||||
|
private TestBean testBean;
|
||||||
|
|
||||||
|
@Resource @Lazy
|
||||||
|
public void setTestBean(TestBean testBean) {
|
||||||
|
this.testBean = testBean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static class NullFactory {
|
private static class NullFactory {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue