本文是小马克课程笔记,介绍了Spring对Java EE API的整合,涉及Web、数据存储、Bean技术等方面。还阐述了Spring编程模型,包括面向对象(契约接口、设计模式、对象继承)、面向切面(动态代理、字节码提升)、面向元编程(注解、配置、泛型)和函数驱动(函数接口、Reactive、模块驱动)等内容。
*@authorRodJohnson*@authorJuergenHoeller*@authorChrisBeams*@seeResourceLoaderAware*@seeApplicationEventPublisherAware*@seeMessageSourceAware*@seeorg.springframework.context.support.ApplicationObjectSupport*@seeorg.springframework.beans.factory.BeanFactoryAware*/publicinterfaceApplicationContextAwareextendsAware{/**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/voidsetApplicationContext(ApplicationContext applicationContext)throwsBeansException;}
publicabstractclassApplicationEventextendsEventObject{/** use serialVersionUID from Spring 1.2 for interoperability. */privatestaticfinallong serialVersionUID =7099057708183571937L;/** System time when the event happened. */privatefinallong timestamp;/**
* Create a new {@code ApplicationEvent}.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/publicApplicationEvent(Object source){super(source);this.timestamp =System.currentTimeMillis();}/**
* Return the system time in milliseconds when the event occurred.
*/publicfinallonggetTimestamp(){returnthis.timestamp;}}
ApplicationEvent 基于java的标准事件EventObject
publicclassEventObjectimplementsjava.io.Serializable{privatestaticfinallong serialVersionUID =5516075349620653480L;/**
* The object on which the Event initially occurred.
*/protectedtransientObject source;/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @exception IllegalArgumentException if source is null.
*/publicEventObject(Object source){if(source ==null)thrownewIllegalArgumentException("null source");this.source = source;}/**
* The object on which the Event initially occurred.
*
* @return The object on which the Event initially occurred.
*/publicObjectgetSource(){return source;}/**
* Returns a String representation of this EventObject.
*
* @return A a String representation of this EventObject.
*/publicStringtoString(){returngetClass().getName()+"[source="+ source +"]";}}
有一个简单的实现
通过事件的方式让监听器进行状态的回调
publicclassSimpleApplicationEventMulticasterextendsAbstractApplicationEventMulticaster{@NullableprivateExecutor taskExecutor;@NullableprivateErrorHandler errorHandler;@OverridepublicvoidmulticastEvent(ApplicationEvent event){multicastEvent(event,resolveDefaultEventType(event));}@OverridepublicvoidmulticastEvent(finalApplicationEvent event,@NullableResolvableType eventType){ResolvableType type =(eventType !=null? eventType :resolveDefaultEventType(event));Executor executor =getTaskExecutor();for(ApplicationListener<?> listener :getApplicationListeners(event, type)){if(executor !=null){
executor.execute(()->invokeListener(listener, event));}else{invokeListener(listener, event);}}}}@FunctionalInterfacepublicinterfaceApplicationListener<EextendsApplicationEvent>extendsEventListener{/**
* Handle an application event.
* @param event the event to respond to
*/voidonApplicationEvent(E event);}
finalclassJdkDynamicAopProxyimplementsAopProxy,InvocationHandler,Serializable{privatestaticfinallong serialVersionUID =5531744639992436476L;privatestaticfinalLog logger =LogFactory.getLog(JdkDynamicAopProxy.class);privatefinalAdvisedSupport advised;privateboolean equalsDefined;privateboolean hashCodeDefined;publicJdkDynamicAopProxy(AdvisedSupport config)throwsAopConfigException{Assert.notNull(config,"AdvisedSupport must not be null");if(config.getAdvisors().length ==0&& config.getTargetSource()==AdvisedSupport.EMPTY_TARGET_SOURCE){thrownewAopConfigException("No advisors and no TargetSource specified");}else{this.advised = config;}}publicObjectgetProxy(){returnthis.getProxy(ClassUtils.getDefaultClassLoader());}}publicinterfaceAopProxy{ObjectgetProxy();ObjectgetProxy(@NullableClassLoader var1);}
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic@interfaceRepository{/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/@AliasFor(annotation =Component.class)Stringvalue()default"";}
配置
Profiles可以认为是不同的用户配置对不同的系统来进行区分例如(dev sit uat pod)
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Repeatable(PropertySources.class)public@interfacePropertySource{/**
* Indicate the name of this property source. If omitted, a name will
* be generated based on the description of the underlying resource.
* @see org.springframework.core.env.PropertySource#getName()
* @see org.springframework.core.io.Resource#getDescription()
*/Stringname()default"";/**
* Indicate the resource location(s) of the properties file to be loaded.
* <p>Both traditional and XML-based properties file formats are supported
* — for example, {@code "classpath:/com/myco/app.properties"}
* or {@code "file:/path/to/file.xml"}.
* <p>Resource location wildcards (e.g. **/*.properties) are not permitted;
* each location must evaluate to exactly one {@code .properties} resource.
* <p>${...} placeholders will be resolved against any/all property sources already
* registered with the {@code Environment}. See {@linkplain PropertySource above}
* for examples.
* <p>Each location will be added to the enclosing {@code Environment} as its own
* property source, and in the order declared.
*/String[]value();/**
* Indicate if failure to find the a {@link #value() property resource} should be
* ignored.
* <p>{@code true} is appropriate if the properties file is completely optional.
* Default is {@code false}.
* @since 4.0
*/booleanignoreResourceNotFound()defaultfalse;/**
* A specific character encoding for the given resources, e.g. "UTF-8".
* @since 4.3
*/Stringencoding()default"";/**
* Specify a custom {@link PropertySourceFactory}, if any.
* <p>By default, a default factory for standard resource files will be used.
* @since 4.3
* @see org.springframework.core.io.support.DefaultPropertySourceFactory
* @see org.springframework.core.io.support.ResourcePropertySource
*/Class<?extendsPropertySourceFactory>factory()defaultPropertySourceFactory.class;}
@FunctionalInterfacepublicinterfaceApplicationListener<EextendsApplicationEvent>extendsEventListener{/**
* Handle an application event.
* @param event the event to respond to
*/voidonApplicationEvent(E event);}