小马克课程笔记
Spring 对 Java EE API 整合
| JSR 规范 | Spring 支持版本 | 代表实现 |
|---|---|---|
| Servlet + JSP(JSR 035) | 1.0 + | DispatcherServlet |
| JSTL(JSR 052) | 1.0 + | JstlView |
| JavaServer Faces(JSR 127) | 1.1 + | FacesContextUtils |
| Portlet(JSR 168) | 2.0 - 4.2 | DispatcherPortlet |
| SOAP(JSR 067) | 2.5 + | SoapFaultException |
| WebServices(JSR 109) | 2.5 + | CommonAnnotationBeanPostProcessor |
| WebSocket(JSR 356) | 4.0 + | WebSocketHandler |
| JSR 规范 | Spring 支持版本 | 代表实现 |
|---|---|---|
| JDO(JSR 12) | 1.0 - 4.2 | JdoTemplate |
| JTA(JSR 907) | 1.0 + | JtaTransactionManager |
| JPA(EJB 3.0 JSR 220的成员) | 2.0 + | JpaTransactionManager |
| Java Caching API(JSR 107) | 3.2 + | JCacheCache |
| JSR 规范 | Spring 支持版本 | 代表实现 |
|---|---|---|
| JMS(JSR 914) | 1.1 + JmsTemplate | |
| EJB 2.0 (JSR 19) | 1.0 + AbstractStatefulSessionBean | |
| Dependency Injection for Java(JSR 330) | 2.5 + | AutowiredAnnotationBeanPostProcessor |
| Bean Validation(JSR 303) | 3.0 + | LocalValidatorFactoryBean |
-
资源相关
- JSR 官方网址:https://jcp.org/
- 小马哥 JSR 收藏:https://github.com/mercyblitz/jsr
- Spring 官方文档根路径:https://docs.spring.io/spring/docs/
Spring 编程模型

面向对象
契约接口
-
Aware
- 这是一种模式 Aware前面是类型
- 会注入ApplicationContext 同理BeanFactoryAware也是一样
- 这是一种接口的方式,称为Aware接口回调
- 每当Bean实现这样一种接口的时候会回调一个对象(ApplicationContext 、BeanFactory)
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @see ResourceLoaderAware
* @see ApplicationEventPublisherAware
* @see MessageSourceAware
* @see org.springframework.context.support.ApplicationObjectSupport
* @see org.springframework.beans.factory.BeanFactoryAware
*/
public interface ApplicationContextAware extends Aware {
/**
* 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
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
设计模式
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened. */
private final long 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})
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Return the system time in milliseconds when the event occurred.
*/
public final long getTimestamp() {
return this.timestamp;
}
}
ApplicationEvent 基于java的标准事件EventObject
public class EventObject implements java.io.Serializable {
private static final long serialVersionUID = 5516075349620653480L;
/**
* The object on which the Event initially occurred.
*/
protected transient Object source;
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @exception IllegalArgumentException if source is null.
*/
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
/**
* The object on which the Event initially occurred.
*
* @return The object on which the Event initially occurred.
*/
public Object getSource() {
return source;
}
/**
* Returns a String representation of this EventObject.
*
* @return A a String representation of this EventObject.
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
- 有一个简单的实现
- 通过事件的方式让监听器进行状态的回调
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Nullable
private Executor taskExecutor;
@Nullable
private ErrorHandler errorHandler;
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType 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);
}
}
}
}
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
-
组合模式
- CompositeCacheManager
- 实现了CacheManager而后组合了更多成员List<CacheManager> cacheManagers
- 此处是多个缓存合并后按照同一个处理方式进行处理
- CompositeCacheManager
public class CompositeCacheManager implements CacheManager, InitializingBean {
private final List<CacheManager> cacheManagers = new ArrayList<>();
private boolean fallbackToNoOpCache = false;
}
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
private static final String RETURN_RESULT_SET_PREFIX = "#result-set-";
private static final String RETURN_UPDATE_COUNT_PREFIX = "#update-count-";
private boolean ignoreWarnings = true;
private int fetchSize = -1;
private int maxRows = -1;
private int queryTimeout = -1;
private boolean skipResultsProcessing = false;
private boolean skipUndeclaredResults = false;
private boolean resultsMapCaseInsensitive = false;
@Nullable
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(this.obtainDataSource());
Object var10;
try {
Connection conToUse = this.createConnectionProxy(con);
var10 = action.doInConnection(conToUse);
} catch (SQLException var8) {
String sql = getSql(action);
DataSourceUtils.releaseConnection(con, this.getDataSource());
con = null;
throw this.translateException("ConnectionCallback", sql, var8);
} finally {
DataSourceUtils.releaseConnection(con, this.getDataSource());
}
return var10;
}
@Nullable
public <T> T execute(StatementCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(this.obtainDataSource());
Statement stmt = null;
Object var11;
try {
stmt = con.createStatement();
this.applyStatementSettings(stmt);
T result = action.doInStatement(stmt);
this.handleWarnings(stmt);
var11 = result;
} catch (SQLException var9) {
String sql = getSql(action);
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, this.getDataSource());
con = null;
throw this.translateException("StatementCallback", sql, var9);
} finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, this.getDataSource());
}
return var11;
}
}
对象继承
- 很多Abstract*抽象类
- 例如AbstractApplicationContext 、AbstractBeanFactory 有很多继承实现类
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {}
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport
implements ConfigurableBeanFactory {}
面向切面
动态代理
- JdkDynamicAopProxy 代理了AopProxy
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private static final long serialVersionUID = 5531744639992436476L;
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
private final AdvisedSupport advised;
private boolean equalsDefined;
private boolean hashCodeDefined;
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
} else {
this.advised = config;
}
}
public Object getProxy() {
return this.getProxy(ClassUtils.getDefaultClassLoader());
}
}
public interface AopProxy {
Object getProxy();
Object getProxy(@Nullable ClassLoader var1);
}
字节码提升
- AopProxy的多种实现之CglibAopProxy
- 这是Spring为了保证版本稳定性将Cglib内联进自己核心框架中了(asm自动资源管理也是类似的方式)
- asm是Cglib的基础,是对java字节码的类似于汇编一样的操作
lass CglibAopProxy implements AopProxy, Serializable {
private static final int AOP_PROXY = 0;
private static final int INVOKE_TARGET = 1;
private static final int NO_OVERRIDE = 2;
private static final int DISPATCH_TARGET = 3;
private static final int DISPATCH_ADVISED = 4;
private static final int INVOKE_EQUALS = 5;
private static final int INVOKE_HASHCODE = 6;
protected static final Log logger = LogFactory.getLog(CglibAopProxy.class);
private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap();
protected final AdvisedSupport advised;
@Nullable
protected Object[] constructorArgs;
@Nullable
protected Class<?>[] constructorArgTypes;
private final transient CglibAopProxy.AdvisedDispatcher advisedDispatcher;
private transient Map<Method, Integer> fixedInterceptorMap = Collections.emptyMap();
private transient int fixedInterceptorOffset;
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
} else {
this.advised = config;
this.advisedDispatcher = new CglibAopProxy.AdvisedDispatcher(this.advised);
}
}
}
面向元编程
注解
- Component (组件)注解
- 被ComponentScan注解或者相应注解扫描到会变成一个Bean
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default "**/*.class";
boolean useDefaultFilters() default true;
ComponentScan.Filter[] includeFilters() default {};
ComponentScan.Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
- Component 的派生类Repository (Service和Controller等也是这种方式)
- 标注了@Component就意味着Repository 等同于Component
- 进行标注是因为注解没有继承关系所以只能进行源标注
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
/**
* 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)
String value() default "";
}
配置
- Profiles可以认为是不同的用户配置对不同的系统来进行区分例如(dev sit uat pod)
public interface Environment extends PropertyResolver {
String[] getActiveProfiles();
String[] getDefaultProfiles();
/** @deprecated */
@Deprecated
boolean acceptsProfiles(String... var1);
boolean acceptsProfiles(Profiles var1);
}
- 属性(数据源来自于多个PropertySource )
public interface PropertyResolver {
boolean containsProperty(String var1);
@Nullable
String getProperty(String var1);
String getProperty(String var1, String var2);
@Nullable
<T> T getProperty(String var1, Class<T> var2);
<T> T getProperty(String var1, Class<T> var2, T var3);
String getRequiredProperty(String var1) throws IllegalStateException;
<T> T getRequiredProperty(String var1, Class<T> var2) throws IllegalStateException;
String resolvePlaceholders(String var1);
String resolveRequiredPlaceholders(String var1) throws IllegalArgumentException;
}
- PropertySource
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
/**
* 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()
*/
String name() 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
*/
boolean ignoreResourceNotFound() default false;
/**
* A specific character encoding for the given resources, e.g. "UTF-8".
* @since 4.3
*/
String encoding() 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<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
泛型
- GenericTypeResolver
public final class GenericTypeResolver {
private static final Map<Class<?>, Map<TypeVariable, Type>> typeVariableCache = new ConcurrentReferenceHashMap();
private GenericTypeResolver() {
}
}
public interface TypeVariable<D extends GenericDeclaration>
extends Type, AnnotatedElement {
}
- ResolvableType
- 有示例如何获取泛型
public class ResolvableType implements Serializable {
}

函数驱动
函数接口
- 有且仅有一个抽象方法,排除掉Object里面的equals,hashCode方法以及一些default实现,此时无论标注或者不标注@FunctionalInterface 都可以认为是函数接口
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
- 例如
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
Reactive
- Reactive的实现框架Reactor
- 编程框架 Mono、Flux
- Mono可以简单认为是个单一对象(0或者1个)
- Flux是个集合对象
public abstract class Mono<T> implements CorePublisher<T> {
static final BiPredicate EQUALS_BIPREDICATE = Object::equals;
public Mono() {
}
}
public abstract class Flux<T> implements CorePublisher<T> {
static final BiFunction TUPLE2_BIFUNCTION = Tuples::of;
static final Supplier LIST_SUPPLIER = ArrayList::new;
static final Supplier SET_SUPPLIER = HashSet::new;
static final BooleanSupplier ALWAYS_BOOLEAN_SUPPLIER = () -> {
return true;
};
static final BiPredicate OBJECT_EQUAL = Object::equals;
static final Function IDENTITY_FUNCTION = Function.identity();
public Flux() {
}
}
模块驱动
- Enable
- 例如EnableCaching 激活整个缓存部分
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
}
- EnableTransactionManagement 激活整个事务相关模块
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default 2147483647;
}
- EnableWebMvc激活WebMVC
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}
- EnableWebFlux 激活WebFlux
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebFluxConfiguration.class})
public @interface EnableWebFlux {
}
本文是小马克课程笔记,介绍了Spring对Java EE API的整合,涉及Web、数据存储、Bean技术等方面。还阐述了Spring编程模型,包括面向对象(契约接口、设计模式、对象继承)、面向切面(动态代理、字节码提升)、面向元编程(注解、配置、泛型)和函数驱动(函数接口、Reactive、模块驱动)等内容。

被折叠的 条评论
为什么被折叠?



