文章目录
- 三、Spring框架
- 1、什么是Spring
- 2、使用Spring框架的好处是什么
- 3、Spring框架是设计目标,设计理念,和核心是什么?
- 4、Spring优缺点
- 5、Spring框架中都用到了哪些设计模式
- 6、什么是SpringIOC容器
- 7、IOC的优点
- 8、Spring IOC的实现机制
- 9、BeanFactory和ApplicationContext有什么区别
- 10、ApplicationContext通常的实现是什么
- 11、Spring支持的几种bean的作用域
- 12、Spring框架中的单例bean是线程安全的吗
- 13、Spring如何处理线程并发问题
- 14、什么是AOP
- 15、SpringAOP的底层是什么?
- 16、如何给Spring容器配置元数据?(也就是创建Bean)
- 17、依赖注入的几种方式
- 18、@Required注解怎么用
- 19、@Autowired、@Resource、@Qualifier
- 20、BeanFactory和FactoryBean的区别
- 21、Spring中一个bean装配的过程
三、Spring框架
1、什么是Spring
spring是一个轻量级的Java开发框架,最早由Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑和其他各层的耦合问题,简化开发
2、使用Spring框架的好处是什么
3、Spring框架是设计目标,设计理念,和核心是什么?
**Spring设计目标:**Spring为开发者提供一个一站式轻量级应用开发平台
Spring设计理念: 在JavaEE开发中,支持POJO和JavaBean开发方式,使应用面向接口开发,充分支持OO(面向对象)设计方法;Spring通过IoC容器实现对象耦合关系的管理,并实现依赖反转,将对象之间的依赖关系交给IoC容器,实现解耦;
Spring框架的核心:IOC容器和AOP模块。通过IOC容器管理pojo对象以及他们之间的耦合关系;通过AOP以动态代理的方式增强服务
IOC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件
4、Spring优缺点
优点:
- 方便解耦,简化开发。Spring是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理
- AOP编程的支持。Spring提供面向切面的编程,可以方便的实现程序对权限的拦截、运行监控等功能
- 声明式事务的支持。只需要通过配置就可以完成对事物的管理,无需手动编程
- 方便程序的测试,Spring对Junit4的支持,可以通过注解方便的测试Spring程序
- 方便集成各种优秀的框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持
- 降低JavaEE API的使用难度
缺点:
- Spring依赖反射,反射影响性能
- 使用门槛高
- 配置多
5、Spring框架中都用到了哪些设计模式
1、工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例
2、单例模式:Bean默认为单例模式
3、代理模式:SpringAop功能用到了JDK动态代理和CGLIB字节码生成技术
4、模板方法模式:用来解决代码重复问题,例如RestTemplate、JmsTemplate
5、观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener
6、什么是SpringIOC容器
控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期
7、IOC的优点
- IOC或依赖注入把应用的代码量降到最低
- 它使应用容易测试,单元测试不在需要单例和JNDI查找机制
- 最小的代价和最小的侵入性使松耦合得以实现
- IOC容器支持加载服务时的饿汉式初始化和懒加载
8、Spring IOC的实现机制
Spring中IOC的实现原理就是工厂模式加反射机制
interface Fruit {
public abstract void eat();
}
class Apple implements Fruit {
public void eat(){
System.out.println("Apple");
}
}
class Orange implements Fruit {
public void eat(){
System.out.println("Orange");
}
}
class Factory {
public static Fruit getInstance(String ClassName) {
Fruit f=null;
try {
f=(Fruit)Class.forName(ClassName).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class Client {
public static void main(String[] a) {
Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple");
if(f!=null){
f.eat();
}
}
}
9、BeanFactory和ApplicationContext有什么区别
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
依赖关系
BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。
ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
- 继承MessageSource,因此支持国际化。
- 统一的资源文件访问方式。
- 提供在监听器中注册bean的事件。
- 同时加载多个配置文件。
- 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
加载方式
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
创建方式
BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。
注册方式
BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。
10、ApplicationContext通常的实现是什么
FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
11、Spring支持的几种bean的作用域
- singleton:bean在每个Spring IOC容器中只有一个实例
- prototype:一个bean的定义可以有多个实例
- request:每次的http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效
- session:在一个http的session中,一个bean定义对应一个实例,该作用域仅在基于web的Spring ApplicationContext情形下有效
- global-session:在一个全局的Http Session中,一个bean定义对应着一个实例,该作用域仅在基于web的Spring ApplicationContext情形下有效
12、Spring框架中的单例bean是线程安全的吗
不是,Spring框架中的单例bean不是线程安全的。
spring中的bean默认是单例模式,spring框架没有对单例的bean进行多线程的封装处理。
实际上大部分时候springBean是无状态的,所以从某种程度上来说,bean也是安全的,但如果bean有状态的话,那就需要开发者自己去保证线程的安全了,最简单的就是改变bean的作用域,把“singleton”变更为prototype,这样请求bean相当于new Bean()了,所以就可以保证线程安全
- 有状态,指有数据存储功能
- 无状态,指不会保存数据
13、Spring如何处理线程并发问题
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal
14、什么是AOP
AOP面向切面编程,与传统的OOP相辅相成。在OOP中,我们以类来作为我们的基本单元,而AOP中的基本单元是切面。AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理
1、AspectJ是静态代理的增强,在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ织入到java字节码中
2、SpringAOP使用的动态代理,动态代理不会修改字节码,而是每次运行的时在内存中临时生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并在特定的切点做了增强处理
15、SpringAOP的底层是什么?
SpringAOP的底层是基于动态代理来实现的,动态代理有两种,一种是基于JDK的动态代理,一种的基于cglib的动态代理。SpringAOP中没有默认选择哪一种动态代理的方式,而是根据被代理的对象是类还是接口。
如果是接口,采用的就是JDK的动态代理;如果是类,采用的就是cglib的动态代理
16、如何给Spring容器配置元数据?(也就是创建Bean)
1、基于XML配置文件
<!-- id可以理解为对象名 -->
<bean id="" class="">
</bean>
2、基于注解的配置
@Controller
@Service
@Resposity
//开启注解配置
<context: annotation-config/>
3、基于java的配置
@Confirguration和@Bean搭配使用
17、依赖注入的几种方式
依赖注入其实就是给我们的对象中的属性值赋一个初始值
基于xml配置文件实现
1、构造器注入
2、setter注入
3、接口注入
18、@Required注解怎么用
@Required应用bean属性的setter方法。该注解表示该字段属性值必须有,如果没有会抛异常
19、@Autowired、@Resource、@Qualifier
@Autowired,按照类型自动装配
@Resourcee,先按照名称自动装配,然后再按照类型装配
@Qualifier,当有多个类型相同的bean,并希望仅使用属性装配其中的一个bean时,可以使用@Qualifier和@Autowired注解搭配使用
20、BeanFactory和FactoryBean的区别
BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似