设计模式-类扩展-非代理

装饰器模式

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&trade; 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();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值