@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");
|
||||
* 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.WebServiceRef;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
|
|
@ -414,6 +416,44 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
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.
|
||||
* @param element the descriptor for the annotated field/method
|
||||
|
|
@ -527,6 +567,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
*/
|
||||
private class ResourceElement extends LookupElement {
|
||||
|
||||
private final boolean lazyLookup;
|
||||
|
||||
public ResourceElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
|
||||
super(member, pd);
|
||||
Resource resource = ae.getAnnotation(Resource.class);
|
||||
|
|
@ -552,11 +594,14 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
this.name = resourceName;
|
||||
this.lookupType = resourceType;
|
||||
this.mappedName = resource.mappedName();
|
||||
Lazy lazy = ae.getAnnotation(Lazy.class);
|
||||
this.lazyLookup = (lazy != null && lazy.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -437,6 +437,60 @@ public class CommonAnnotationBeanPostProcessorTests {
|
|||
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 {
|
||||
|
||||
|
|
@ -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")
|
||||
private static class NullFactory {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue