Merge branch '5.1.x'
This commit is contained in:
commit
d25783329a
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -133,7 +133,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
|||
|
||||
private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
|
||||
|
||||
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
|
||||
|
||||
|
|
@ -236,9 +236,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
|||
@Override
|
||||
public Object getEarlyBeanReference(Object bean, String beanName) {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
this.earlyProxyReferences.add(cacheKey);
|
||||
}
|
||||
this.earlyProxyReferences.put(cacheKey, bean);
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +295,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
|
|||
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
|
||||
if (bean != null) {
|
||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
||||
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
|
||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -133,8 +133,7 @@ public interface BeanFactory {
|
|||
* Will ask the parent factory if the bean cannot be found in this factory instance.
|
||||
* @param name the name of the bean to retrieve
|
||||
* @return an instance of the bean
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean definition
|
||||
* with the specified name
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
|
||||
* @throws BeansException if the bean could not be obtained
|
||||
*/
|
||||
Object getBean(String name) throws BeansException;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -29,6 +29,8 @@ import org.springframework.util.ObjectUtils;
|
|||
/**
|
||||
* A simple descriptor for an injection point, pointing to a method/constructor
|
||||
* parameter or a field. Exposed by {@link UnsatisfiedDependencyException}.
|
||||
* Also available as an argument for factory methods, reacting to the
|
||||
* requesting injection point for building a customized bean instance.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.3
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -337,8 +337,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
|||
* including its bean name.
|
||||
* <p>This is effectively a variant of {@link #getBean(Class)} which preserves the
|
||||
* bean name of the matching instance.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass.
|
||||
* {@code null} is disallowed.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass
|
||||
* @return the bean name plus bean instance
|
||||
* @throws NoSuchBeanDefinitionException if no matching bean was found
|
||||
* @throws NoUniqueBeanDefinitionException if more than one matching bean was found
|
||||
|
|
@ -348,6 +347,22 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
|||
*/
|
||||
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
|
||||
|
||||
/**
|
||||
* Resolve a bean instance for the given bean name, providing a dependency descriptor
|
||||
* for exposure to target factory methods.
|
||||
* <p>This is effectively a variant of {@link #getBean(String, Class)} which supports
|
||||
* factory methods with an {@link org.springframework.beans.factory.InjectionPoint}
|
||||
* argument.
|
||||
* @param name the name of the bean to look up
|
||||
* @param descriptor the dependency descriptor for the requesting injection point
|
||||
* @return the corresponding bean instance
|
||||
* @throws NoSuchBeanDefinitionException if there is no bean with the specified name
|
||||
* @throws BeansException if the bean could not be created
|
||||
* @since 5.1.5
|
||||
* @see #getBean(String, Class)
|
||||
*/
|
||||
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
|
||||
|
||||
/**
|
||||
* Resolve the specified dependency against the beans defined in this factory.
|
||||
* @param descriptor the descriptor for the dependency (field/method/constructor)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -58,6 +58,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
|||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.InjectionPoint;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
|
@ -337,12 +338,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
return initializeBean(beanName, existingBean, bd);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
|
||||
return resolveDependency(descriptor, requestingBeanName, null, null);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Specialized methods for fine-grained control over the bean lifecycle
|
||||
|
|
@ -446,6 +441,28 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Delegate methods for resolving injection points
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Object resolveBeanByName(String name, DependencyDescriptor descriptor) {
|
||||
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
|
||||
try {
|
||||
return getBean(name, descriptor.getDependencyType());
|
||||
}
|
||||
finally {
|
||||
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
|
||||
return resolveDependency(descriptor, requestingBeanName, null, null);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of relevant AbstractBeanFactory template methods
|
||||
//---------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -512,13 +512,19 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
Set<String> autowiredBeanNames;
|
||||
String name = element.name;
|
||||
|
||||
if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&
|
||||
factory instanceof AutowireCapableBeanFactory && !factory.containsBean(name)) {
|
||||
autowiredBeanNames = new LinkedHashSet<>();
|
||||
resource = ((AutowireCapableBeanFactory) factory).resolveDependency(
|
||||
element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);
|
||||
if (resource == null) {
|
||||
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
|
||||
if (factory instanceof AutowireCapableBeanFactory) {
|
||||
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
|
||||
DependencyDescriptor descriptor = element.getDependencyDescriptor();
|
||||
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
|
||||
autowiredBeanNames = new LinkedHashSet<>();
|
||||
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
|
||||
if (resource == null) {
|
||||
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
|
||||
}
|
||||
}
|
||||
else {
|
||||
resource = beanFactory.resolveBeanByName(name, descriptor);
|
||||
autowiredBeanNames = Collections.singleton(name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -212,7 +212,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
/** Statically specified listeners. */
|
||||
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
|
||||
|
||||
/** ApplicationEvents published early. */
|
||||
/** Local listeners registered before refresh. */
|
||||
@Nullable
|
||||
private Set<ApplicationListener<?>> earlyApplicationListeners;
|
||||
|
||||
/** ApplicationEvents published before the multicaster setup. */
|
||||
@Nullable
|
||||
private Set<ApplicationEvent> earlyApplicationEvents;
|
||||
|
||||
|
|
@ -483,7 +487,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
this.beanFactoryPostProcessors.add(postProcessor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the list of BeanFactoryPostProcessors that will get applied
|
||||
* to the internal BeanFactory.
|
||||
|
|
@ -578,6 +581,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
* active flag as well as performing any initialization of property sources.
|
||||
*/
|
||||
protected void prepareRefresh() {
|
||||
// Switch to active.
|
||||
this.startupDate = System.currentTimeMillis();
|
||||
this.closed.set(false);
|
||||
this.active.set(true);
|
||||
|
|
@ -591,13 +595,23 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
}
|
||||
}
|
||||
|
||||
// Initialize any placeholder property sources in the context environment
|
||||
// Initialize any placeholder property sources in the context environment.
|
||||
initPropertySources();
|
||||
|
||||
// Validate that all properties marked as required are resolvable
|
||||
// Validate that all properties marked as required are resolvable:
|
||||
// see ConfigurablePropertyResolver#setRequiredProperties
|
||||
getEnvironment().validateRequiredProperties();
|
||||
|
||||
// Store pre-refresh ApplicationListeners...
|
||||
if (this.earlyApplicationListeners == null) {
|
||||
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
|
||||
}
|
||||
else {
|
||||
// Reset local application listeners to pre-refresh state.
|
||||
this.applicationListeners.clear();
|
||||
this.applicationListeners.addAll(this.earlyApplicationListeners);
|
||||
}
|
||||
|
||||
// Allow for the collection of early ApplicationEvents,
|
||||
// to be published once the multicaster is available...
|
||||
this.earlyApplicationEvents = new LinkedHashSet<>();
|
||||
|
|
@ -982,6 +996,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
* @see #registerShutdownHook()
|
||||
*/
|
||||
protected void doClose() {
|
||||
// Check whether an actual close attempt is necessary...
|
||||
if (this.active.get() && this.closed.compareAndSet(false, true)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Closing " + this);
|
||||
|
|
@ -1016,6 +1031,13 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
// Let subclasses do some final clean-up if they wish...
|
||||
onClose();
|
||||
|
||||
// Reset local application listeners to pre-refresh state.
|
||||
if (this.earlyApplicationListeners != null) {
|
||||
this.applicationListeners.clear();
|
||||
this.applicationListeners.addAll(this.earlyApplicationListeners);
|
||||
}
|
||||
|
||||
// Switch to inactive.
|
||||
this.active.set(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1302,7 +1324,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
@Nullable
|
||||
protected MessageSource getInternalParentMessageSource() {
|
||||
return (getParent() instanceof AbstractApplicationContext ?
|
||||
((AbstractApplicationContext) getParent()).messageSource : getParent());
|
||||
((AbstractApplicationContext) getParent()).messageSource : getParent());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -21,6 +21,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.junit.Rule;
|
||||
|
|
@ -228,6 +229,22 @@ public class ConfigurationClassProcessingTests {
|
|||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithAdaptiveResourcePrototypes() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(ConfigWithPrototypeBean.class, AdaptiveResourceInjectionPoints.class);
|
||||
ctx.refresh();
|
||||
|
||||
AdaptiveResourceInjectionPoints adaptive = ctx.getBean(AdaptiveResourceInjectionPoints.class);
|
||||
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
|
||||
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
|
||||
|
||||
adaptive = ctx.getBean(AdaptiveResourceInjectionPoints.class);
|
||||
assertEquals("adaptiveInjectionPoint1", adaptive.adaptiveInjectionPoint1.getName());
|
||||
assertEquals("setAdaptiveInjectionPoint2", adaptive.adaptiveInjectionPoint2.getName());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationWithPostProcessor() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
|
|
@ -444,6 +461,21 @@ public class ConfigurationClassProcessingTests {
|
|||
}
|
||||
|
||||
|
||||
@Scope("prototype")
|
||||
static class AdaptiveResourceInjectionPoints {
|
||||
|
||||
@Resource(name = "adaptive1")
|
||||
public TestBean adaptiveInjectionPoint1;
|
||||
|
||||
public TestBean adaptiveInjectionPoint2;
|
||||
|
||||
@Resource(name = "adaptive2")
|
||||
public void setAdaptiveInjectionPoint2(TestBean adaptiveInjectionPoint2) {
|
||||
this.adaptiveInjectionPoint2 = adaptiveInjectionPoint2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class ConfigWithPostProcessor extends ConfigWithPrototypeBean {
|
||||
|
||||
@Value("${myProp}")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
|
|
@ -411,6 +411,11 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||
throw new UnsupportedOperationException("Dependency resolution not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException {
|
||||
throw new UnsupportedOperationException("Dependency resolution not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) {
|
||||
|
|
|
|||
|
|
@ -1044,7 +1044,8 @@ load an entire Spring IoC container instance.
|
|||
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to
|
||||
use constructors for mandatory dependencies and setter methods or configuration methods
|
||||
for optional dependencies. Note that use of the <<beans-required-annotation,@Required>>
|
||||
annotation on a setter method can be used to make the property be a required dependency.
|
||||
annotation on a setter method can be used to make the property be a required dependency;
|
||||
however, constructor injection with programmatic validation of arguments is preferable.
|
||||
|
||||
The Spring team generally advocates constructor injection, as it lets you implement
|
||||
application components as immutable objects and ensures that required dependencies
|
||||
|
|
@ -1076,8 +1077,8 @@ The container performs bean dependency resolution as follows:
|
|||
describes all the beans. Configuration metadata can be specified by XML, Java code, or
|
||||
annotations.
|
||||
* For each bean, its dependencies are expressed in the form of properties, constructor
|
||||
arguments, or arguments to the static-factory method( if you use that instead of
|
||||
a normal constructor). These dependencies are provided to the bean, when the bean is
|
||||
arguments, or arguments to the static-factory method (if you use that instead of a
|
||||
normal constructor). These dependencies are provided to the bean, when the bean is
|
||||
actually created.
|
||||
* Each property or constructor argument is an actual definition of the value to set, or
|
||||
a reference to another bean in the container.
|
||||
|
|
@ -3070,8 +3071,8 @@ of a bean. This section groups them as follows:
|
|||
[[beans-factory-lifecycle]]
|
||||
=== Lifecycle Callbacks
|
||||
|
||||
To interact with the container's management of the bean lifecycle, you can implement the
|
||||
Spring `InitializingBean` and `DisposableBean` interfaces. The container calls
|
||||
To interact with the container's management of the bean lifecycle, you can implement
|
||||
the Spring `InitializingBean` and `DisposableBean` interfaces. The container calls
|
||||
`afterPropertiesSet()` for the former and `destroy()` for the latter to let the bean
|
||||
perform certain actions upon initialization and destruction of your beans.
|
||||
|
||||
|
|
@ -3079,11 +3080,11 @@ perform certain actions upon initialization and destruction of your beans.
|
|||
====
|
||||
The JSR-250 `@PostConstruct` and `@PreDestroy` annotations are generally considered best
|
||||
practice for receiving lifecycle callbacks in a modern Spring application. Using these
|
||||
annotations means that your beans are not coupled to Spring-specific interfaces. For
|
||||
details, see <<beans-postconstruct-and-predestroy-annotations>>.
|
||||
annotations means that your beans are not coupled to Spring-specific interfaces.
|
||||
For details, see <<beans-postconstruct-and-predestroy-annotations>>.
|
||||
|
||||
If you do not want to use the JSR-250 annotations but you still want to remove
|
||||
coupling, consider using of `init-method` and `destroy-method` object definition metadata.
|
||||
coupling, consider `init-method` and `destroy-method` bean definition metadata.
|
||||
====
|
||||
|
||||
Internally, the Spring Framework uses `BeanPostProcessor` implementations to process any
|
||||
|
|
@ -3099,7 +3100,6 @@ startup and shutdown process, as driven by the container's own lifecycle.
|
|||
The lifecycle callback interfaces are described in this section.
|
||||
|
||||
|
||||
|
||||
[[beans-factory-lifecycle-initializingbean]]
|
||||
==== Initialization Callbacks
|
||||
|
||||
|
|
@ -3138,8 +3138,8 @@ no-argument signature. With Java configuration, you can use the `initMethod` att
|
|||
}
|
||||
----
|
||||
|
||||
The preceding example has almost exactly the same effect as the following example (which
|
||||
consists of two listings):
|
||||
The preceding example has almost exactly the same effect as the following example
|
||||
(which consists of two listings):
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
|
|
@ -4313,11 +4313,18 @@ example:
|
|||
This annotation indicates that the affected bean property must be populated at
|
||||
configuration time, through an explicit property value in a bean definition or through
|
||||
autowiring. The container throws an exception if the affected bean property has not been
|
||||
populated. This allows for eager and explicit failure, avoiding `NullPointerException` instances
|
||||
or the like later on. We still recommend that you put assertions into the bean
|
||||
class itself (for example, into an init method). Doing so enforces those required
|
||||
populated. This allows for eager and explicit failure, avoiding `NullPointerException`
|
||||
instances or the like later on. We still recommend that you put assertions into the
|
||||
bean class itself (for example, into an init method). Doing so enforces those required
|
||||
references and values even when you use the class outside of a container.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The `@Required` annotation is formally deprecated as of Spring Framework 5.1, in favor
|
||||
of using constructor injection for required settings (or a custom implementation of
|
||||
`InitializingBean.afterPropertiesSet()` along with bean property setter methods).
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[beans-autowired-annotation]]
|
||||
|
|
@ -5149,14 +5156,14 @@ attribute set to `true`, it is selected.
|
|||
[[beans-resource-annotation]]
|
||||
=== Injection with `@Resource`
|
||||
|
||||
Spring also supports injection by using the JSR-250 `@Resource` annotation on fields or
|
||||
bean property setter methods. This is a common pattern in Java EE 5 and 6 (for example,
|
||||
in JSF 1.2 managed beans or JAX-WS 2.0 endpoints). Spring supports this pattern for
|
||||
Spring-managed objects as well.
|
||||
Spring also supports injection by using the JSR-250 `@Resource` annotation
|
||||
(`javax.annotation.Resource`) on fields or bean property setter methods.
|
||||
This is a common pattern in Java EE: for example, in JSF-managed beans and JAX-WS
|
||||
endpoints. Spring supports this pattern for Spring-managed objects as well.
|
||||
|
||||
`@Resource` takes a name attribute. By default, Spring interprets that value as the
|
||||
bean name to be injected. In other words, it follows by-name semantics, as
|
||||
demonstrated in the following example:
|
||||
`@Resource` takes a name attribute. By default, Spring interprets that value as
|
||||
the bean name to be injected. In other words, it follows by-name semantics,
|
||||
as demonstrated in the following example:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
|
|
@ -5207,7 +5214,7 @@ and resolves well known resolvable dependencies: the `BeanFactory`,
|
|||
interfaces.
|
||||
|
||||
Thus, in the following example, the `customerPreferenceDao` field first looks for a bean
|
||||
named customerPreferenceDao and then falls back to a primary type match for the type
|
||||
named "customerPreferenceDao" and then falls back to a primary type match for the type
|
||||
`CustomerPreferenceDao`:
|
||||
|
||||
[source,java,indent=0]
|
||||
|
|
@ -5236,15 +5243,16 @@ named customerPreferenceDao and then falls back to a primary type match for the
|
|||
=== Using `@PostConstruct` and `@PreDestroy`
|
||||
|
||||
The `CommonAnnotationBeanPostProcessor` not only recognizes the `@Resource` annotation
|
||||
but also the JSR-250 lifecycle annotations. Introduced in Spring 2.5, the support
|
||||
for these annotations offers yet another alternative to those described in
|
||||
but also the JSR-250 lifecycle annotations: `javax.annotation.PostConstruct` and
|
||||
`javax.annotation.PreDestroy`. Introduced in Spring 2.5, the support for these
|
||||
annotations offers an alternative to the lifecycle callback mechanism described in
|
||||
<<beans-factory-lifecycle-initializingbean,initialization callbacks>> and
|
||||
<<beans-factory-lifecycle-disposablebean,destruction callbacks>>. Provided that the
|
||||
`CommonAnnotationBeanPostProcessor` is registered within the Spring
|
||||
`ApplicationContext`, a method carrying one of these annotations is invoked at the same
|
||||
point in the lifecycle as the corresponding Spring lifecycle interface method or
|
||||
explicitly declared callback method. In the following example, the cache is
|
||||
pre-populated upon initialization and cleared upon destruction:
|
||||
`CommonAnnotationBeanPostProcessor` is registered within the Spring `ApplicationContext`,
|
||||
a method carrying one of these annotations is invoked at the same point in the lifecycle
|
||||
as the corresponding Spring lifecycle interface method or explicitly declared callback
|
||||
method. In the following example, the cache is pre-populated upon initialization and
|
||||
cleared upon destruction:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
|
|
@ -5263,9 +5271,19 @@ pre-populated upon initialization and cleared upon destruction:
|
|||
}
|
||||
----
|
||||
|
||||
NOTE: For details about the effects of combining various lifecycle mechanisms, see
|
||||
For details about the effects of combining various lifecycle mechanisms, see
|
||||
<<beans-factory-lifecycle-combined-effects>>.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Like `@Resource`, the `@PostConstruct` and `@PreDestroy` annotation types were a part
|
||||
of the standard Java libraries from JDK 6 to 8. However, the entire `javax.annotation`
|
||||
package got separated from the core Java modules in JDK 9 and eventually removed in
|
||||
JDK 11. If needed, the `javax.annotation-api` artifact needs to be obtained via Maven
|
||||
Central now, simply to be added to the application's classpath like any other library.
|
||||
====
|
||||
|
||||
|
||||
|
||||
|
||||
[[beans-classpath-scanning]]
|
||||
|
|
@ -6722,8 +6740,8 @@ The following example shows how to prevent an automatic destruction callback for
|
|||
}
|
||||
----
|
||||
|
||||
Also, with `@Bean` methods, you typically use programmatic JNDI lookups,
|
||||
either by using Spring's `JndiTemplate` or `JndiLocatorDelegate` helpers or straight JNDI
|
||||
Also, with `@Bean` methods, you typically use programmatic JNDI lookups, either by
|
||||
using Spring's `JndiTemplate` or `JndiLocatorDelegate` helpers or straight JNDI
|
||||
`InitialContext` usage but not the `JndiObjectFactoryBean` variant (which would force
|
||||
you to declare the return type as the `FactoryBean` type instead of the actual target
|
||||
type, making it harder to use for cross-reference calls in other `@Bean` methods that
|
||||
|
|
@ -6790,7 +6808,7 @@ Spring offers a convenient way of working with scoped dependencies through
|
|||
<<beans-factory-scopes-other-injection,scoped proxies>>. The easiest way to create such
|
||||
a proxy when using the XML configuration is the `<aop:scoped-proxy/>` element.
|
||||
Configuring your beans in Java with a `@Scope` annotation offers equivalent support with
|
||||
the `proxyMode` attribute. The default is no proxy ( `ScopedProxyMode.NO`), but you can
|
||||
the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`), but you can
|
||||
specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`.
|
||||
|
||||
If you port the scoped proxy example from the XML reference documentation (see
|
||||
|
|
@ -8847,9 +8865,9 @@ exist, the listener uses `/WEB-INF/applicationContext.xml` as a default. When th
|
|||
parameter does exist, the listener separates the `String` by using predefined
|
||||
delimiters (comma, semicolon, and whitespace) and uses the values as locations where
|
||||
application contexts are searched. Ant-style path patterns are supported as well.
|
||||
Examples are `/WEB-INF/{asterisk}Context.xml` (for all files with names that end with `Context.xml`
|
||||
and that reside in the `WEB-INF` directory) and `/WEB-INF/**/*Context.xml`( for all such files
|
||||
in any subdirectory of `WEB-INF`).
|
||||
Examples are `/WEB-INF/{asterisk}Context.xml` (for all files with names that end with
|
||||
`Context.xml` and that reside in the `WEB-INF` directory) and `/WEB-INF/**/*Context.xml`
|
||||
(for all such files in any subdirectory of `WEB-INF`).
|
||||
|
||||
|
||||
|
||||
|
|
@ -8860,17 +8878,17 @@ It is possible to deploy a Spring `ApplicationContext` as a RAR file, encapsulat
|
|||
context and all of its required bean classes and library JARs in a Java EE RAR deployment
|
||||
unit. This is the equivalent of bootstrapping a stand-alone `ApplicationContext` (only hosted
|
||||
in Java EE environment) being able to access the Java EE servers facilities. RAR deployment
|
||||
is a more natural alternative to a scenario of deploying a headless WAR file -- in effect, a WAR
|
||||
file without any HTTP entry points that is used only for bootstrapping a Spring
|
||||
is a more natural alternative to a scenario of deploying a headless WAR file -- in effect,
|
||||
a WAR file without any HTTP entry points that is used only for bootstrapping a Spring
|
||||
`ApplicationContext` in a Java EE environment.
|
||||
|
||||
RAR deployment is ideal for application contexts that do not need HTTP entry points but
|
||||
rather consist only of message endpoints and scheduled jobs. Beans in such a context can
|
||||
use application server resources such as the JTA transaction manager and JNDI-bound JDBC
|
||||
`DataSource` instances and JMS `ConnectionFactory` instances and can also register with the
|
||||
platform's JMX server -- all through Spring's standard transaction management and JNDI
|
||||
and JMX support facilities. Application components can also interact with the
|
||||
application server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.
|
||||
`DataSource` instances and JMS `ConnectionFactory` instances and can also register with
|
||||
the platform's JMX server -- all through Spring's standard transaction management and JNDI
|
||||
and JMX support facilities. Application components can also interact with the application
|
||||
server's JCA `WorkManager` through Spring's `TaskExecutor` abstraction.
|
||||
|
||||
See the javadoc of the
|
||||
{api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`SpringContextResourceAdapter`]
|
||||
|
|
@ -8889,13 +8907,13 @@ and the corresponding Spring XML bean definition file(s) (typically
|
|||
. Drop the resulting RAR file into your
|
||||
application server's deployment directory.
|
||||
|
||||
NOTE: Such RAR deployment units are usually self-contained. They do not expose components to
|
||||
the outside world, not even to other modules of the same application. Interaction with a
|
||||
NOTE: Such RAR deployment units are usually self-contained. They do not expose components
|
||||
to the outside world, not even to other modules of the same application. Interaction with a
|
||||
RAR-based `ApplicationContext` usually occurs through JMS destinations that it shares with
|
||||
other modules. A RAR-based `ApplicationContext` may also, for example, schedule some jobs
|
||||
or react to new files in the file system (or the like). If it needs to allow synchronous
|
||||
access from the outside, it could (for example) export RMI endpoints, which may
|
||||
be used by other application modules on the same machine.
|
||||
access from the outside, it could (for example) export RMI endpoints, which may be used
|
||||
by other application modules on the same machine.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue