zoukankan      html  css  js  c++  java
  • spring源码分析之@Conditional

    根源在AnnotationConfigApplicationContext和AnnotationConfigWebApplicationContext,以AnnotationConfigApplicationContext为例:

    1.构造方法

        /**
         * Create a new AnnotationConfigApplicationContext, deriving bean definitions
         * from the given annotated classes and automatically refreshing the context.
         * @param annotatedClasses one or more annotated classes,
         * e.g. {@link Configuration @Configuration} classes
         */
        public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
            this();
            register(annotatedClasses);
            refresh();
        }
    
        /**
         * Create a new AnnotationConfigApplicationContext, scanning for bean definitions
         * in the given packages and automatically refreshing the context.
         * @param basePackages the packages to check for annotated classes
         */
        public AnnotationConfigApplicationContext(String... basePackages) {
            this();
            scan(basePackages);
            refresh();
        }

    一种是注解类方式,一种是扫描方式,殊途同归。以注解类来分析:

        /**
         * Register one or more annotated classes to be processed.
         * <p>Note that {@link #refresh()} must be called in order for the context
         * to fully process the new classes.
         * @param annotatedClasses one or more annotated classes,
         * e.g. {@link Configuration @Configuration} classes
         * @see #scan(String...)
         * @see #refresh()
         */
        public void register(Class<?>... annotatedClasses) {
            Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
            this.reader.register(annotatedClasses);
        }

    2. 实现方法AnnotatedBeanDefinitionReader

        public void register(Class<?>... annotatedClasses) {
            for (Class<?> annotatedClass : annotatedClasses) {
                registerBean(annotatedClass);
            }
        }

    具体逻辑还是在该类内部:

        @SuppressWarnings("unchecked")
        public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
            registerBean(annotatedClass, null, qualifiers);
        }
    
        @SuppressWarnings("unchecked")
        public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
            if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
                return;
            }
    
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            abd.setScope(scopeMetadata.getScopeName());
            String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
            AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            if (qualifiers != null) {
                for (Class<? extends Annotation> qualifier : qualifiers) {
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    }
                    else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    }
                    else {
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }
    
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        }

    3.分析逻辑

    3.1 ConditionEvaluator

        /**
         * Determine if an item should be skipped based on {@code @Conditional} annotations.
         * @param metadata the meta data
         * @param phase the phase of the call
         * @return if the item should be skipped
         */
        public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) {
            if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
                return false;
            }
    
            if (phase == null) {
                if (metadata instanceof AnnotationMetadata &&
                        ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
                    return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
                }
                return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
            }
    
            List<Condition> conditions = new ArrayList<>();
            for (String[] conditionClasses : getConditionClasses(metadata)) {
                for (String conditionClass : conditionClasses) {
                    Condition condition = getCondition(conditionClass, this.context.getClassLoader());
                    conditions.add(condition);
                }
            }
    
            AnnotationAwareOrderComparator.sort(conditions);
    
            for (Condition condition : conditions) {
                ConfigurationPhase requiredPhase = null;
                if (condition instanceof ConfigurationCondition) {
                    requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
                }
                if (requiredPhase == null || requiredPhase == phase) {
                    if (!condition.matches(this.context, metadata)) {
                        return true;
                    }
                }
            }
    
            

    3.2 大鱼AnnotationConfigUtils来了

    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
            if (qualifiers != null) {
                for (Class<? extends Annotation> qualifier : qualifiers) {
                    if (Primary.class == qualifier) {
                        abd.setPrimary(true);
                    }
                    else if (Lazy.class == qualifier) {
                        abd.setLazyInit(true);
                    }
                    else {
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    }
                }
            }

    通用注解(lazy、primary、DependsOn、role、description)实现:

        static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
            if (metadata.isAnnotated(Lazy.class.getName())) {
                abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));
            }
            else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) {
                abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value"));
            }
    
            if (metadata.isAnnotated(Primary.class.getName())) {
                abd.setPrimary(true);
            }
            if (metadata.isAnnotated(DependsOn.class.getName())) {
                abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value"));
            }
    
            if (abd instanceof AbstractBeanDefinition) {
                AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
                if (metadata.isAnnotated(Role.class.getName())) {
                    absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue());
                }
                if (metadata.isAnnotated(Description.class.getName())) {
                    absBd.setDescription(attributesFor(metadata, Description.class).getString("value"));
                }
            }
        }

    3.3 钓上大鱼,处理注解的相关processor在这里注册:

    /**
         * Register all relevant annotation post processors in the given registry.
         * @param registry the registry to operate on
         * @param source the configuration source element (already extracted)
         * that this registration was triggered from. May be {@code null}.
         * @return a Set of BeanDefinitionHolders, containing all bean definitions
         * that have actually been registered by this call
         */
        public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
                BeanDefinitionRegistry registry, Object source) {
    
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
            if (beanFactory != null) {
                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
                }
                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
                }
            }
    
            Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4);
    
            if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
            if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
            if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition();
                try {
                    def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                            AnnotationConfigUtils.class.getClassLoader()));
                }
                catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
                }
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
            }
            if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
            }
    
            return beanDefs;
        }
    
        private static BeanDefinitionHolder registerPostProcessor(
                BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
    
            definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registry.registerBeanDefinition(beanName, definition);
            return new BeanDefinitionHolder(definition, beanName);
        }

    3.3.1 ConfigurationClassPostProcessor

    /**
     * {@link BeanFactoryPostProcessor} used for bootstrapping processing of
     * {@link Configuration @Configuration} classes.
     *
     * <p>Registered by default when using {@code <context:annotation-config/>} or
     * {@code <context:component-scan/>}. Otherwise, may be declared manually as
     * with any other BeanFactoryPostProcessor.
     *
     * <p>This post processor is {@link Ordered#HIGHEST_PRECEDENCE} as it is important
     * that any {@link Bean} methods declared in Configuration classes have their
     * respective bean definitions registered before any other BeanFactoryPostProcessor
     * executes.
     *
     * @author Chris Beams
     * @author Juergen Hoeller
     * @author Phillip Webb
     * @since 3.0
     */
    public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
            PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
    }

    3.3.2 AutowiredAnnotationBeanPostProcessor

    /**
     * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
     * that autowires annotated fields, setter methods and arbitrary config methods.
     * Such members to be injected are detected through a Java 5 annotation: by default,
     * Spring's {@link Autowired @Autowired} and {@link Value @Value} annotations.
     *
     * <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
     * if available, as a direct alternative to Spring's own {@code @Autowired}.
     *
     * <p>Only one constructor (at max) of any given bean class may carry this
     * annotation with the 'required' parameter set to {@code true},
     * indicating <i>the</i> constructor to autowire when used as a Spring bean.
     * If multiple <i>non-required</i> constructors carry the annotation, they
     * will be considered as candidates for autowiring. The constructor with
     * the greatest number of dependencies that can be satisfied by matching
     * beans in the Spring container will be chosen. If none of the candidates
     * can be satisfied, then a default constructor (if present) will be used.
     * An annotated constructor does not have to be public.
     *
     * <p>Fields are injected right after construction of a bean, before any
     * config methods are invoked. Such a config field does not have to be public.
     *
     * <p>Config methods may have an arbitrary name and any number of arguments; each of
     * those arguments will be autowired with a matching bean in the Spring container.
     * Bean property setter methods are effectively just a special case of such a
     * general config method. Config methods do not have to be public.
     *
     * <p>Note: A default AutowiredAnnotationBeanPostProcessor will be registered
     * by the "context:annotation-config" and "context:component-scan" XML tags.
     * Remove or turn off the default annotation configuration there if you intend
     * to specify a custom AutowiredAnnotationBeanPostProcessor bean definition.
     * <p><b>NOTE:</b> Annotation injection will be performed <i>before</i> XML injection;
     * thus the latter configuration will override the former for properties wired through
     * both approaches.
     *
     * <p>In addition to regular injection points as discussed above, this post-processor
     * also handles Spring's {@link Lookup @Lookup} annotation which identifies lookup
     * methods to be replaced by the container at runtime. This is essentially a type-safe
     * version of {@code getBean(Class, args)} and {@code getBean(String, args)},
     * See {@link Lookup @Lookup's javadoc} for details.
     *
     * @author Juergen Hoeller
     * @author Mark Fisher
     * @author Stephane Nicoll
     * @since 2.5
     * @see #setAutowiredAnnotationType
     * @see Autowired
     * @see Value
     */
    public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
            implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
    }

    3.3.3 RequiredAnnotationBeanPostProcessor

    /**
     * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
     * that enforces required JavaBean properties to have been configured.
     * Required bean properties are detected through a Java 5 annotation:
     * by default, Spring's {@link Required} annotation.
     *
     * <p>The motivation for the existence of this BeanPostProcessor is to allow
     * developers to annotate the setter properties of their own classes with an
     * arbitrary JDK 1.5 annotation to indicate that the container must check
     * for the configuration of a dependency injected value. This neatly pushes
     * responsibility for such checking onto the container (where it arguably belongs),
     * and obviates the need (<b>in part</b>) for a developer to code a method that
     * simply checks that all required properties have actually been set.
     *
     * <p>Please note that an 'init' method may still need to implemented (and may
     * still be desirable), because all that this class does is enforce that a
     * 'required' property has actually been configured with a value. It does
     * <b>not</b> check anything else... In particular, it does not check that a
     * configured value is not {@code null}.
     *
     * <p>Note: A default RequiredAnnotationBeanPostProcessor will be registered
     * by the "context:annotation-config" and "context:component-scan" XML tags.
     * Remove or turn off the default annotation configuration there if you intend
     * to specify a custom RequiredAnnotationBeanPostProcessor bean definition.
     *
     * @author Rob Harrop
     * @author Juergen Hoeller
     * @since 2.0
     * @see #setRequiredAnnotationType
     * @see Required
     */
    public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
            implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
    }

    3.3.4 CommonAnnotationBeanPostProcessor

    /**
     * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
     * that supports common Java annotations out of the box, in particular the JSR-250
     * annotations in the {@code javax.annotation} package. These common Java
     * annotations are supported in many Java EE 5 technologies (e.g. JSF 1.2),
     * as well as in Java 6's JAX-WS.
     *
     * <p>This post-processor includes support for the {@link javax.annotation.PostConstruct}
     * and {@link javax.annotation.PreDestroy} annotations - as init annotation
     * and destroy annotation, respectively - through inheriting from
     * {@link InitDestroyAnnotationBeanPostProcessor} with pre-configured annotation types.
     *
     * <p>The central element is the {@link javax.annotation.Resource} annotation
     * for annotation-driven injection of named beans, by default from the containing
     * Spring BeanFactory, with only {@code mappedName} references resolved in JNDI.
     * The {@link #setAlwaysUseJndiLookup "alwaysUseJndiLookup" flag} enforces JNDI lookups
     * equivalent to standard Java EE 5 resource injection for {@code name} references
     * and default names as well. The target beans can be simple POJOs, with no special
     * requirements other than the type having to match.
     *
     * <p>The JAX-WS {@link javax.xml.ws.WebServiceRef} annotation is supported too,
     * analogous to {@link javax.annotation.Resource} but with the capability of creating
     * specific JAX-WS service endpoints. This may either point to an explicitly defined
     * resource by name or operate on a locally specified JAX-WS service class. Finally,
     * this post-processor also supports the EJB 3 {@link javax.ejb.EJB} annotation,
     * analogous to {@link javax.annotation.Resource} as well, with the capability to
     * specify both a local bean name and a global JNDI name for fallback retrieval.
     * The target beans can be plain POJOs as well as EJB 3 Session Beans in this case.
     *
     * <p>The common annotations supported by this post-processor are available in
     * Java 6 (JDK 1.6) as well as in Java EE 5/6 (which provides a standalone jar for
     * its common annotations as well, allowing for use in any Java 5 based application).
     *
     * <p>For default usage, resolving resource names as Spring bean names,
     * simply define the following in your application context:
     *
     * <pre class="code">
     * &lt;bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/&gt;</pre>
     *
     * For direct JNDI access, resolving resource names as JNDI resource references
     * within the Java EE application's "java:comp/env/" namespace, use the following:
     *
     * <pre class="code">
     * &lt;bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"&gt;
     *   &lt;property name="alwaysUseJndiLookup" value="true"/&gt;
     * &lt;/bean&gt;</pre>
     *
     * {@code mappedName} references will always be resolved in JNDI,
     * allowing for global JNDI names (including "java:" prefix) as well. The
     * "alwaysUseJndiLookup" flag just affects {@code name} references and
     * default names (inferred from the field name / property name).
     *
     * <p><b>NOTE:</b> A default CommonAnnotationBeanPostProcessor will be registered
     * by the "context:annotation-config" and "context:component-scan" XML tags.
     * Remove or turn off the default annotation configuration there if you intend
     * to specify a custom CommonAnnotationBeanPostProcessor bean definition!
     * <p><b>NOTE:</b> Annotation injection will be performed <i>before</i> XML injection; thus
     * the latter configuration will override the former for properties wired through
     * both approaches.
     *
     * @author Juergen Hoeller
     * @since 2.5
     * @see #setAlwaysUseJndiLookup
     * @see #setResourceFactory
     * @see org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
     * @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
     */
    @SuppressWarnings("serial")
    public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
            implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
    }

    3.3.5 PersistenceAnnotationBeanPostProcessor

    /**
     * BeanPostProcessor that processes {@link javax.persistence.PersistenceUnit}
     * and {@link javax.persistence.PersistenceContext} annotations, for injection of
     * the corresponding JPA resources {@link javax.persistence.EntityManagerFactory}
     * and {@link javax.persistence.EntityManager}. Any such annotated fields or methods
     * in any Spring-managed object will automatically be injected.
     *
     * <p>This post-processor will inject sub-interfaces of {@code EntityManagerFactory}
     * and {@code EntityManager} if the annotated fields or methods are declared as such.
     * The actual type will be verified early, with the exception of a shared ("transactional")
     * {@code EntityManager} reference, where type mismatches might be detected as late
     * as on the first actual invocation.
     *
     * <p>Note: In the present implementation, PersistenceAnnotationBeanPostProcessor
     * only supports {@code @PersistenceUnit} and {@code @PersistenceContext}
     * with the "unitName" attribute, or no attribute at all (for the default unit).
     * If those annotations are present with the "name" attribute at the class level,
     * they will simply be ignored, since those only serve as deployment hint
     * (as per the Java EE specification).
     *
     * <p>This post-processor can either obtain EntityManagerFactory beans defined
     * in the Spring application context (the default), or obtain EntityManagerFactory
     * references from JNDI ("persistence unit references"). In the bean case,
     * the persistence unit name will be matched against the actual deployed unit,
     * with the bean name used as fallback unit name if no deployed name found.
     * Typically, Spring's {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean}
     * will be used for setting up such EntityManagerFactory beans. Alternatively,
     * such beans may also be obtained from JNDI, e.g. using the {@code jee:jndi-lookup}
     * XML configuration element (with the bean name matching the requested unit name).
     * In both cases, the post-processor definition will look as simple as this:
     *
     * <pre class="code">
     * &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/&gt;</pre>
     *
     * In the JNDI case, specify the corresponding JNDI names in this post-processor's
     * {@link #setPersistenceUnits "persistenceUnits" map}, typically with matching
     * {@code persistence-unit-ref} entries in the Java EE deployment descriptor.
     * By default, those names are considered as resource references (according to the
     * Java EE resource-ref convention), located underneath the "java:comp/env/" namespace.
     * For example:
     *
     * <pre class="code">
     * &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"&gt;
     *   &lt;property name="persistenceUnits"&gt;
     *     &lt;map/gt;
     *       &lt;entry key="unit1" value="persistence/unit1"/&gt;
     *       &lt;entry key="unit2" value="persistence/unit2"/&gt;
     *     &lt;/map/gt;
     *   &lt;/property&gt;
     * &lt;/bean&gt;</pre>
     *
     * In this case, the specified persistence units will always be resolved in JNDI
     * rather than as Spring-defined beans. The entire persistence unit deployment,
     * including the weaving of persistent classes, is then up to the Java EE server.
     * Persistence contexts (i.e. EntityManager references) will be built based on
     * those server-provided EntityManagerFactory references, using Spring's own
     * transaction synchronization facilities for transactional EntityManager handling
     * (typically with Spring's {@code @Transactional} annotation for demarcation
     * and {@link org.springframework.transaction.jta.JtaTransactionManager} as backend).
     *
     * <p>If you prefer the Java EE server's own EntityManager handling, specify entries
     * in this post-processor's {@link #setPersistenceContexts "persistenceContexts" map}
     * (or {@link #setExtendedPersistenceContexts "extendedPersistenceContexts" map},
     * typically with matching {@code persistence-context-ref} entries in the
     * Java EE deployment descriptor. For example:
     *
     * <pre class="code">
     * &lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"&gt;
     *   &lt;property name="persistenceContexts"&gt;
     *     &lt;map/gt;
     *       &lt;entry key="unit1" value="persistence/context1"/&gt;
     *       &lt;entry key="unit2" value="persistence/context2"/&gt;
     *     &lt;/map/gt;
     *   &lt;/property&gt;
     * &lt;/bean&gt;</pre>
     *
     * If the application only obtains EntityManager references in the first place,
     * this is all you need to specify. If you need EntityManagerFactory references
     * as well, specify entries for both "persistenceUnits" and "persistenceContexts",
     * pointing to matching JNDI locations.
     *
     * <p><b>NOTE: In general, do not inject EXTENDED EntityManagers into STATELESS beans,
     * i.e. do not use {@code @PersistenceContext} with type {@code EXTENDED} in
     * Spring beans defined with scope 'singleton' (Spring's default scope).</b>
     * Extended EntityManagers are <i>not</i> thread-safe, hence they must not be used
     * in concurrently accessed beans (which Spring-managed singletons usually are).
     *
     * <p>Note: A default PersistenceAnnotationBeanPostProcessor will be registered
     * by the "context:annotation-config" and "context:component-scan" XML tags.
     * Remove or turn off the default annotation configuration there if you intend
     * to specify a custom PersistenceAnnotationBeanPostProcessor bean definition.
     *
     * @author Rod Johnson
     * @author Juergen Hoeller
     * @since 2.0
     * @see javax.persistence.PersistenceUnit
     * @see javax.persistence.PersistenceContext
     */
    @SuppressWarnings("serial")
    public class PersistenceAnnotationBeanPostProcessor
            implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
            MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {

    3.3.6 EventListenerMethodProcessor

    /**
     * Register {@link EventListener} annotated method as individual {@link ApplicationListener}
     * instances.
     *
     * @author Stephane Nicoll
     * @author Juergen Hoeller
     * @since 4.2
     */
    public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware {
    }

    3.3.7 DefaultEventListenerFactory

    /**
     * Default {@link EventListenerFactory} implementation that supports the
     * regular {@link EventListener} annotation.
     * <p>Used as "catch-all" implementation by default.
     *
     * @author Stephane Nicoll
     * @since 4.2
     */
    public class DefaultEventListenerFactory implements EventListenerFactory, Ordered {
    }

    扯远了,就此打住!

  • 相关阅读:
    关于oracle的一些操作
    关于List的一些操作
    XSS挑战赛(2)
    阿里云图床搭建
    XSS挑战赛(1)
    Shiro remeberMe反序列化漏洞复现(Shiro-550)
    HTTP慢速拒绝服务攻击(Slow HTTP Dos)
    从Excel获取整列内容进行批量扫描
    PHP代码审计分段讲解(14)
    PHP代码审计分段讲解(13)
  • 原文地址:https://www.cnblogs.com/davidwang456/p/6274583.html
Copyright © 2011-2022 走看看