spring 的设计模式(23种…)
(面试题)说说BeanFactory和FactoryBean的实现原理和区别? spring 中你还知道哪些设计模式??
1.简单工厂模式
实质: 由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。
实现方式: BeanFactory
实现原理:
Bean的xml 配置文件==>转化BeanDefinition对象==>注册对象BeanDefinitionRegistry=>BeanFactory
设计意义 :1.松耦合。 beanFactory,由它来解决bean之间的依赖问题
2.通过Spring接口的暴露, bean的额外处理
总结: BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等
2.工厂模式
实质: 实现了FactoryBean接口的bean是一类叫做factory的bean 。
实现方式: FactoryBean
实现原理:因为实现了FactoryBean接口,所以返回的不是SqlSessionFactoryBean的实例,而是它的 SqlSessionFactoryBean.getObject()的返回值。
-
典型的例子有Spring与MyBatis的结合。
-
代码示例:
-
//mybatis 入门案例 @Test public void testDemo1() throws IOException { /*创建SqlSessionFactory*/ String resource = "mybatis/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); /*从SqlSessionFactory中获取sqlSession*/ SqlSession sqlSession = sqlSessionFactory.openSession(); /*获取mapper接口,执行接口方法*/ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); /*Mybatis为接口创建了一个代理对象 知识点: 框架中通过接口调用方法时,如果没有实现类,则为其创建代理对象 代理对象~实现类 */ List<User> userList = userMapper.findAll(); sqlSession.close(); }
总结:FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑,简化了实例化bean 的过程,Spring自身提供了70多个FactoryBean的实现
以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身
3.单例模式
实质:保证一个类仅有一个实例,并提供一个访问它的全局访问点 (多线程访问,加锁 syncronized)
Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建。
4.适配器模式
实现场景:SpringMVC中的适配器HandlerAdatper
实现原理:HandlerAdatper根据Handler规则执行不同的Handler
总结::HandlerAdatper使得Handler的扩展变得容易,只需要增加一个新的Handler和一个对应的HandlerAdapter即可。因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller时,只需要增加一个适配器类就完成了SpringMVC的扩展了
5.装饰器模式
实现方式:Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。
实质:
-
动态地给一个对象添加一些额外的职责。
-
就增加功能来说,Decorator模式相比生成子类更为灵活。
-
示例代码:java 中装饰器
InputStream in = new BufferedInputStream( new FileInputStream(new File("E:\ready\1.txt")));
这里按HikariProxyConnection 数据库连接的代理对象源码展示
6.代理模式
实现方式:AOP底层,就是动态代理模式的实现。
- 动态代理:在内存中构建的,不需要手动编写代理类
- 静态代理:需要手工编写代理类,代理类引用被代理对象。
实现原理:切面在应用运行的时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象创建动态的创建一个代理对象。SpringAOP就是以这种方式织入切面的。
织入:把切面应用到目标对象并创建新的代理对象的过程。
7.模版方法模式
实质:是模板方法模式和回调模式的结合,是Template Method不需要继承的另一种实现方式。Spring几乎所有的外接扩展都采用这种模式。
最大的好处:代码复用,减少重复代码。除了子类要实现的特定方法,其他方法及方法调用顺序都在父类中预先写好了。
-
共同的方法:所有子类都会用到的代码
-
不同的方法:子类要覆盖的方法,分为两种:
-
抽象方法:父类中的是抽象方法,子类必须覆盖
-
钩子方法:父类中是一个空方法,子类继承了默认也是空的
示例:RestTemplate对象
public class ConsumerController {`
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/doRestEcho1")
public String doRestEcho01(){
//1.定义要调用的远端服务的url
String url="http://localhost:8081/provider/echo/8090";
//2.基于restTemplate对象中的相关方法进行服务调用
return restTemplate.getForObject(url, String.class);
}
JDBC的抽象和对Hibernate的集成,都采用了一种理念或者处理方式,那就是模板方法模式与相应的Callback接口相结合。采用模板方法模式是为了以一种统一而集中的方式来处理资源的获取和释放。
8.中介者模式
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
9.享元模式
在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建
10.空对象模式
一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。
11.观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
12.责任链模式
…
还没补完全,有时间再补…