Spring框架的设计模式
Spring 的核心功能是 IOC 容器以及 AOP 面向切面编程,同样也引入很多设计模式,提高代码的扩展性和灵活性。
简单工厂模式
Spring 中的 BeanFactory 就是简单工厂模式的体现,BeanFactory 是 Spring IOC 容器中的一个核心接口,
public interface BeanFactory { Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType); Object getBean(String name, Object... args); <T> T getBean(Class<T> requiredType); <T> T getBean(Class<T> requiredType, Object... args);}
通过工厂类的方法 getBean 来获取对象实例,这是典型的简单工厂模式,只不过 Spring 是用反射机制来创建 Bean 的。
工厂方法模式
在简单工厂中,由工厂类进行所有的逻辑判断、实例创建;如果不想在工厂类中进行判断,可以为不同的产品提供不同的工厂,不同的工厂生产不同的产品,每一个工厂都只对应一个相应的对象,这就是工厂方法模式。
public interface FactoryBean<T> { T getObject(); Class<?> getObjectType(); boolean isSingleton();}
定义一个类 UserFactoryBean 来实现 FactoryBean 接口,主要是在 getObject 方法里 new 一个 User 对象。这样我们通过 getBean(id) 获得的是该工厂所产生的 User 的实例,而不是 UserFactoryBean 本身的实例,像下面这样:
BeanFactory bf = new ClassPathXmlApplicationContext("user.xml");User userBean = (User) bf.getBean("userFactoryBean");
单例模式
单例模式是指一个类在整个系统运行过程中,只允许产生一个实例。在 Spring 中,Bean 可以被定义为两种模式:prototype(多例)和 singleton(单例),Spring Bean 默认是单例模式
如何实现?
public class DefaultSingletonBeanRegistry {
// 使用了线程安全容器 ConcurrentHashMap,保存各种单实例对象 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>;
protected Object getSingleton(String beanName) { // 先到 HashMap 中拿 Object Object singletonObject = singletonObjects.get(beanName);
// 如果没拿到通过反射创建一个对象实例,并添加到 HashMap 中 if (singletonObject == null) { singletonObjects.put(beanName, Class.forName(beanName).newInstance()); }
// 返回对象实例 return singletonObjects.get(beanName); }}
静态代理模式
所谓代理,是指代理类与目标类实现了相同的接口,客户端必须通过代理才能与目标类进行交互
•抽象接口:定义目标类及代理类的共同接口,这样在任何可以使用目标对象的地方都可以使用代理对象。•目标对象:定义了代理对象所代表的目标对象,专注于业务功能的实现。•代理对象:代理对象内部含有目标对象的引用,收到客户端的调用请求时,代理对象通常不会直接调用目标对象的方法,而是在调用之前和之后实现一些额外的逻辑。
代理模式的好处是,可以在目标对象业务功能的基础上添加一些公共的逻辑,比如我们想给目标对象加入日志、权限管理和事务控制等功能,我们就可以使用代理类来完成,而没必要修改目标类,从而使得目标类保持稳定。这其实是开闭原则的体现,不要随意去修改别人已经写好的代码或者方法。
动态代理模式
静态代理,在程序运行之前就已经编译完成。
动态代理,代理类并不是在 Java 代码中定义的,而是在运行时根据我们在 Java 代码中的“指示”动态生成的。
Java 的java.lang.reflect包里提供了一个 Proxy 类和一个 InvocationHandler 接口,通过这个类和这个接口可以生成动态代理对象。
相比于静态代理,动态代理的优势在于可以很方便地对代理类的方法进行统一的处理,而不用修改代理类中的每个方法。
- 简单易学的机器学习算法——谱聚类(Spectal Clustering)
- oracle数据库 如何查询某个表的约束条件
- 结构体存入文件并且取出
- 【Go 语言社区】使用 Redis 实现排行榜功能
- 使用12c PDB整合环境的总结 (r10笔记第66天)
- 【Go 语言社区】Redis(ZADD)简单排名
- C得到文件的大小
- 【Go 语言社区】Go语言实现选择法排序实例
- 【Go 语言社区】Go语言转换所有字符串为大写或者小写的方法
- Go语言按字节截取字符串的方法
- Go语言中字符串的查找方法小结
- 优化算法——遗传算法
- 每秒执行6000的简单SQL优化(一)(r10笔记第62天)
- 【Go 语言社区】在golang里实现类似try catch 的异常处理机制
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Python简单实现批量下载无版权图片
- Pycharm自动添加文件头注释和函数注释参数
- ClickHouse TTL for Columns and Tables
- Sentence-BERT详解
- 分布式文件系统(HDFS和FastDFS)
- Springboot集成JUnit5优雅进行单元测试
- 音视频相关开发库和资料
- SpringSecurity认证专题之【AuthenticationManager】
- dotnet 让 C# 可以通过动态生成 HLSL 使用 DX12 的 GPU 并行计算库 ComputeSharp 的简介
- 比对软件STAR创建索引文件(index)
- linux|无需解压查看压缩文件内容
- R函数不会写,"抄"总会吧!
- @Resource和@Autowire的区别
- R函数,如何“抄”出水平
- 【STM32H7】第1章 当前主流的小型嵌入式GUI