装饰器模式
AOP获取单例切面
// 装饰者 切面单例工厂
public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory, Serializable {
// 被装饰者 切面工厂
private final MetadataAwareAspectInstanceFactory maaif;
@Nullable
private volatile Object materialized;
/**
* Create a new lazily initializing decorator for the given AspectInstanceFactory.
* @param maaif the MetadataAwareAspectInstanceFactory to decorate
*/
public LazySingletonAspectInstanceFactoryDecorator(MetadataAwareAspectInstanceFactory maaif) {
this.maaif = maaif;
}
// 返回 单例切面
@Override
public Object getAspectInstance() {
// 取 切面实例
Object aspectInstance = this.materialized;
if (aspectInstance == null) {
// 取锁
Object mutex = this.maaif.getAspectCreationMutex();
if (mutex == null) {
aspectInstance = this.maaif.getAspectInstance();
this.materialized = aspectInstance;
}
else {
synchronized (mutex) {
// 双重锁定取切面实例
aspectInstance = this.materialized;
if (aspectInstance == null) {
// 工厂取切面实例
aspectInstance = this.maaif.getAspectInstance();
this.materialized = aspectInstance;
}
}
}
}
return aspectInstance;
}
}
JavaIO 实现 :
BufferedInputStream f = new BufferedInputStream(new FileInputStream(new File(“c:/test.txt”)));
适配器模式
切面匹配拦截器
/**
* Interface allowing extension to the Spring AOP framework to allow
* handling of new Advisors and Advice types.
*
* <p>Implementing objects can create AOP Alliance Interceptors from
* custom advice types, enabling these advice types to be used
* in the Spring AOP framework, which uses interception under the covers.
*
* <p>There is no need for most Spring users to implement this interface;
* do so only if you need to introduce more Advisor or Advice types to Spring.
*
* @author Rod Johnson
*/
public interface AdvisorAdapter {
/**
判断适配器是否支持特定的切面
* Does this adapter understand this advice object? Is it valid to
* invoke the {@code getInterceptors} method with an Advisor that
* contains this advice as an argument?
* @param advice an Advice such as a BeforeAdvice
* @return whether this adapter understands the given advice object
* @see #getInterceptor(org.springframework.aop.Advisor)
* @see org.springframework.aop.BeforeAdvice
*/
boolean supportsAdvice(Advice advice);
/**
将一个 Advisor 适配成 MethodInterceptor
* Return an AOP Alliance MethodInterceptor exposing the behavior of
* the given advice to an interception-based AOP framework.
* <p>Don't worry about any Pointcut contained in the Advisor;
* the AOP framework will take care of checking the pointcut.
* @param advisor the Advisor. The supportsAdvice() method must have
* returned true on this object
* @return an AOP Alliance interceptor for this Advisor. There's
* no need to cache instances for efficiency, as the AOP framework
* caches advice chains.
*/
MethodInterceptor getInterceptor(Advisor advisor);
}
SpringMVC-WebConfig
/**
适配器1:Java8 接口默认方法可代替适配器
* An implementation of {@link WebMvcConfigurer} with empty methods allowing
* subclasses to override only the methods they're interested in.
*
* @author Rossen Stoyanchev
* @since 3.1
* @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made
* possible by a Java 8 baseline) and can be implemented directly without the
* need for this adapter
*/
@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
}
/**
适配器2
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}.
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
* @author Sébastien Deleuze
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Kristine Jetzke
* @author Bruce Brouwer
* @author Artsiom Yudovin
* @author Scott Frederick
* @since 2.0.0
*/
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebMvcAutoConfiguration {
// 内部类,当 外部类WebMvcAutoConfiguration 没有被启用时,此内部类也不会被加载
// 此 自动配置 可以被 WebMvcConfigurationSupport 加载
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
// on the classpath
@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
// 此类可以加载一些配置类
// 生成Bean
}
}
桥接模式
JDBC 对接 多家数据库厂商
->
Spring依赖加载机制:spring.factories
1. 声明配置类,配置类依赖的类:
1. Spring管理的Bean可以注解标识,方法注入
2. 其他类都通过new 引入配置类
2. 配置类写入 META-INF/spring.factories
3. Spring 框架 EnableAutoConfiguration 读取配置类,将配置类Bean 加入到 Spring 管理
@Configuration
// 数据执行 封装到 SqlSessionFactory,同时Spring 也提供了 JdbcTemplate,偏重底层执行的SQL
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
// 数据连接封装到 DataSource,整合 数据库厂商
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisPlusProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {
}
/**
a DataSource uses a URL along with some credentials to establish a database connection.
* <p>A factory for connections to the physical data source that this
* {@code DataSource} object represents. An alternative to the
* {@code DriverManager} facility, a {@code DataSource} object
* is the preferred means of getting a connection. An object that implements
* the {@code DataSource} interface will typically be
* registered with a naming service based on the
* Java™ Naming and Directory (JNDI) API.
* <P>
* The {@code DataSource} interface is implemented by a driver vendor.
* There are three types of implementations:
* <OL>
* <LI>Basic implementation -- produces a standard {@code Connection}
* object
* <LI>Connection pooling implementation -- produces a {@code Connection}
* object that will automatically participate in connection pooling. This
* implementation works with a middle-tier connection pooling manager.
* <LI>Distributed transaction implementation -- produces a
* {@code Connection} object that may be used for distributed
* transactions and almost always participates in connection pooling.
* This implementation works with a middle-tier
* transaction manager and almost always with a connection
* pooling manager.
* </OL>
* <P>
* A {@code DataSource} object has properties that can be modified
* when necessary. For example, if the data source is moved to a different
* server, the property for the server can be changed. The benefit is that
* because the data source's properties can be changed, any code accessing
* that data source does not need to be changed.
* <P>
数据源配置 注册到 DriverManager DriverManager.getConnection(url, props);
* A driver that is accessed via a {@code DataSource} object does not
* register itself with the {@code DriverManager}. Rather, a
* {@code DataSource} object is retrieved through a lookup operation
* and then used to create a {@code Connection} object. With a basic
* implementation, the connection obtained through a {@code DataSource}
* object is identical to a connection obtained through the
* {@code DriverManager} facility.
* <p>
* An implementation of {@code DataSource} must include a public no-arg
* constructor.
*
* @since 1.4
*/
public interface DataSource extends CommonDataSource, Wrapper {
Connection getConnection() throws SQLException;
}
加载数据源执行过程
//1.加载驱动 厂商实现 Driver接口,并在静态块中 将自己存到 DriverManager.registeredDrivers中
Class.forName("com.mysql.jdbc.Driver"); //反射机制加载驱动类
// 2.获取连接Connection
//主机:端口号/数据库名
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
// 3.得到执行sql语句的对象Statement
Statement stmt = conn.createStatement();
// 4.执行sql语句,并返回结果
// mysql 的 Driver 实现类
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
// 调用桥接类
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}
public class DriverManager {
// List of registered JDBC drivers 厂商注册信息
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
// Worker method called by the public getConnection() methods.
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
for (DriverInfo aDriver : registeredDrivers) {
// 取厂商注册,调用厂商方法获取连接
Connection con = aDriver.driver.connect(url, info);
}
}
}
框架依赖关系:
mybatis-plus <- mybatis ,starter-jdbc
mysql / oracle /plsql
Spring Boot整合JPA实现多数据源切换(Oracle、Mysql) - 掘金 (juejin.cn)
小结
代理模式:扩展目标方法,通过重写/实现
装饰器模式:实现类里 定义接口属性,实例化时传入另一个实现类,可以在一个实现类里面调用另一个实现类
适配器模式:适配器 重在 语义——转换(外部传参,内部结构)。其实现方式可以是 接口默认方法,可以是 实现类,也可以是 类型转换接口
桥接模式:无侵入加载外部框架,
一种是定义 被桥接接口,外部类实现,外部类加载时调用桥接类 注册自身信息
一种是 约定大于配置,读配置类
皮一下: 是什么阻止了 方法的循环调用?
MysqlDriver implements Driver{
static {
DriverManager.registerDriver(new Driver());
}
}
DriverManager{
getConnection(){
mysqlDriver.connect();
}
}