1、谈谈你对Spring的理解?
spring 是一个开源的轻量级 JavaBean 容器框架。使用 JavaBean 代替 EJB ,并提供了丰富的企业应用功能,降低应用开发的复杂性。
1)轻量:非入侵性的、所依赖的东西少、资源占用少、部署简单,不同功能选择不同的 jar 组合;
2)容器:工厂模式实现对 JavaBean 进行管理,通过控制反转(IOC)将应用程序的配置和依赖性与应用代码分开;
3)低耦合:通过 xml 配置或注解即可完成 bean 的依赖注入;
4)AOP:通过 xml 配置 或注解即可加入面向切面编程的能力,完成切面功能,如:日志,事务等的统一处理;
5)方便集成:通过配置和简单的对象注入即可集成其他框架,如 Mybatis、Hibernate、Shiro等;
6)丰富的功能:JDBC 层抽象、事务管理、MVC、Java Mail、任务调度、JMX、JMS、JNDI、EJB、动态语言、远程访问、Web Service等。
2、使用Spring框架的好处是什么?
轻量:Spring 是轻量的,基本的版本大约2MB。
控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。 容器:Spring 包含并管理应用中对象的生命周期和配置。
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
3、什么是Ioc?
IoC (Inversion of Control) 控制反转。是一种设计思想,在Java开发中,将你设计好的对象交给容器控制,而不是显式地用代码进行对象的创建。 把创建和查找依赖对象的控制权交给 IoC 容器,由 IoC 容器进行注入、组合对象。这样对象与对象之间是松耦合、便于测试、功能可复用的(减少对象的创建和内存消耗),使得程序的整个体系结构可维护性、灵活性、扩展性变高。然后它底层原理的话是用到了Java的反射机制,之前我有在猜测它是不是用运行时类也就是Class.forname();的方法,因为我们使用Spring的时候是需要在xml文件或者通过注解的方式配置bean的,我们提供了类的全类名,然后IoC容器通过Class.forName()方法,去帮我们创建对象,结果我发现不是,它是使用 ClassLoader来加载类,有兴趣的小伙伴请自行去了解为什么(因为我也不懂)。
使用 IoC 的好处:
1)资源集中管理,实现资源的可配置和易管理;
2)降低了资源的依赖程度,即松耦合;
3)便于测试;
4)功能可复用(减少对象的创建和内存消耗);
5)使得程序的整个体系结构可维护性、灵活性、扩展性变高。
4、什么是AOP?
AOP: Aspect Oriented Programming,面向切面编程。在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。通过预编译和运行期动态代理实现程序功能的统一维护。在Spring框架中,AOP就是一个很重要的功能。
实现 AOP 的方式
1)创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。
2)如果目标对象有实现接口,使用JDK动态代理的方式。如果目标对象没有实现接口,则使用CGLib代理。然后从容器获取代理后的对象,在运行期植入"切面"类的方法。
Spring中AOP实现的两种方式都是基于动态代理的方式下,有想法的小伙伴可以自行思考为什么AOP实现要用动态代理,用静态代理不可以吗?
大体功能
1)Spring声明式事务管理配置;
2) Controller层的参数校验;
3) 使用Spring AOP实现MySQL数据库读写分离案例分析;
4.) 在执行方法前,判断是否具有权限;
5)对部分函数的调用进行日志记录。监控部分重要函数,若抛出指定的异常,可以以短信或邮件方式通知相关人员;
6) 信息过滤,页面转发等等功能。
5、Spring常见注解?
注解名称 | 作用 |
---|---|
@Controller | 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上。 |
@Service | 组合注解(组合了@Component注解),应用在service层(业务逻辑层) |
@Reponsitory | 组合注解(组合了@Component注解),应用在dao层(数据访问层) |
@Component | 表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component还是一个元注解。 |
@Autowired | Spring提供的工具(由Spring的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入。) |
@Resource | JSR-250提供的注解 |
@Inject | JSR-330提供的注解 |
@Configuration | 声明当前类是一个配置类 |
@ComponentScan | 自动扫描指定包下所有使用@Service,@Component,@Controller,@Repository的类并注册 |
@Bean | 注解在方法上,声明当前方法的返回值为一个Bean。返回的Bean对应的类中可以定义init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行init,在销毁之前执行destroy。 |
@Aspect | 声明一个切面(就是说这是一个额外功能) |
@After | 后置建言(advice),在原方法前执行。 |
@Before | 前置建言(advice),在原方法后执行。 |
@Around | 环绕建言(advice),在原方法执行前执行,在原方法执行后再执行(@Around可以实现其他两种advice) |
@PointCut | 声明切点,即定义拦截规则,确定有哪些方法会被切入 |
@Transactional | 声明事务(一般默认配置即可满足要求,当然也可以自定义) |
@Cacheable | 声明数据缓存 |
@EnableAspectJAutoProxy | 开启Spring对AspectJ的支持 |
@Value | 值得注入。经常与Sping EL表达式语言一起使用,注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等等 |
@PropertySource | 指定文件地址。提供了一种方便的、声明性的机制,用于向Spring的环境添加PropertySource。与@configuration类一起使用。 |
@PostConstruct | 标注在方法上,该方法在构造函数执行完成之后执行。 |
@PreDestroy | 标注在方法上,该方法在对象销毁之前执行。 |
@Profile | 表示当一个或多个指定的文件是活动的时,一个组件是有资格注册的。使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。@Profile(“dev”)表示为dev时实例化。 |
@EnableAsync | 开启异步任务支持。注解在配置类上。 |
@Async | 注解在方法上标示这是一个异步方法,在类上标示这个类所有的方法都是异步方法。 |
@EnableScheduling | 注解在配置类上,开启对计划任务的支持。 |
@Scheduled | 注解在方法上,声明该方法是计划任务。支持多种类型的计划任务:cron,fixDelay,fixRate |
@Conditional | 根据满足某一特定条件创建特定的Bean |
@Enable* | 通过简单的@Enable来开启一项功能的支持。所有@Enable注解都有一个@Import注解,@Import是用来导入配置类的,这也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean(1.直接导入配置类2.依据条件选择配置类3.动态注册配置类) |
@RunWith | 这个是Junit的注解,springboot集成了junit。一般在测试类里使用:@RunWith(SpringJUnit4ClassRunner.class) — SpringJUnit4ClassRunner在JUnit环境下提供Sprng TestContext Framework的功能 |
@ContextConfiguration | 用来加载配置ApplicationContext,其中classes属性用来加载配置类:@ContextConfiguration(classes = {TestConfig.class(自定义的一个配置类)}) |
@ActiveProfiles | 用来声明活动的profile–@ActiveProfiles(“prod”(这个prod定义在配置类中)) |
6、Spring有哪些主要模块?
1)Spring Core:框架的最基础部分,提供 IoC 容器,对 bean 进行管理。
2)Spring Context: 基于 bean,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化、校验和调度等功能。
3)Spring DAO: 提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码,还提供了声明性事务管理方法。
4)Spring ORM: 提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、Hibernate、MyBatis 等。
5)Spring AOP: 提供了符合AOP Alliance规范的面向方面的编程实现。
6)Spring Web: 提供了基础的 Web 开发的上下文信息,可与其他 web 进行集成。
7)Spring Web MVC: 提供了 Web 应用的 Model-View-Controller 全功能实现。
7、Spring支持几种bean的作用域?
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情形下有效。
8、spring配置bean实例化有哪些方式。
1)使用类构造器实例化(默认无参数)
<bean id="bean1" class="cn.itcast.spring.b_instance.Bean1"></bean>
2)使用静态工厂方法实例化(简单工厂模式)
调用Bean2Factory的getBean2方法得到bean2
<bean id="bean2" class="cn.itcast.spring.b_instance.Bean2Factory" factory-method="getBean2"></bean>
3)使用实例工厂方法实例化(工厂方法模式)
先创建工厂实例bean3Facory,再通过工厂实例创建目标bean实例
<bean id="bean3Factory" class="cn.itcast.spring.b_instance.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
9、Spring中的单例Beans是线程安全的吗?
Spring 并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean (比如Service类和DAO类)并没有可变的状态,所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如View Model对象),就需要自行保证线程安全,最浅显的解决办法就是多态bean的作用域由“singleton”改为“prototype”。
10、Spring事务的五种隔离级别
DEFAULT(默认):默认的隔离级别,使用数据库默认的事务隔离级别;
READ_UNCOMMITTED(读未提交):这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读;
READ_COMMITTED(读已提交):保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读;
REPEATABLE_READ(可重复读):这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免不可重复读。(mysql默认的事务隔离级别);
SERIALIZABLE(串行化):这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读。
11、Spring事务的七种传播特性
1、PROPAGATION_REQUIRED:如果当前存在事务,方法将加入到这个事务,不存在,就新建一个事务。
2、PROPAGATION_REQUIRED_NEW:当前存在事务,挂起当前事务,新建一个新的事务。
3、PROPAGATION_MANDATORY:当前方法必须运行在事务中,如果不存在事务,就抛出异常。
4、PROPAGATION_NEVER:当前方法不需要运行在事务,如果是事务调用,就抛出异常。
5、PROPAGATION_SUPPORTS:当前存在事务就在事务中运行,不存在就正常执行。
6、PROPAGATION_NOT_SUPPORTED:当前方法不支持事务执行, 如果存在事务,挂起事务,执行完后在继续执行事务。
7、PROPAGATION_NESTED:当父事务调用到这个方法,此时会创建一个savepoint,启动一个嵌套事务执行该方法。如果方法失败,回滚到savepoint点。嵌套事务是外部事务的一部分,如果外部事务失败了,会全部回滚。
12、Spring框架中都用到了那些设计模式?
Spring框架中使用了大量的设计模式,下面列举比较有代表性的:
1)代理模式 -- AOP;
2)单例模式 -- 在Spring配置文件中定义的bean默认为单例模式;
3)模板方法 -- 用来解决代码重复的问题,比如RestTemplate,JpaTemplate;
4)工厂模式 -- BeanFactory用来创建对象的实例;
5)前端控制器 -- Spring提供了DispatcherServlet来对请求进行分发;
6)依赖注入 -- 贯穿BeanFactory/ApplicationContext接口的核心理念。
未完待续