目录
一、Spring框架概述
1、什么是Spring?
2、spring优点有哪些?
二、IOC与DI
3、你知道getBean方法的有几种重载方式吗?
4、Spring有几种依赖注入方式?
三、Spring创建对象
5、Spring创建对象有几种方式?
6、你简单说说Bean有哪些作用域?
7、Bean的生命周期?
四、注解
8、你使用过哪些Spring注解?
9、那@Controller、@Service、@Repository和@Component有什么区别?
10、@Resource与@Autowired的区别?
五、面向切面编程(AOP)
11、什么是AOP?
12、AOP如何手动实现?
13、你在项目中是如何实现的?用过AspectJ吗?
14、有哪些通知类型?
六、JdbcTemplate
15、用过Spring自带的JDBC API技术JdbcTemplate吗?随便说几个常用的方法
七、事务
16、列举spring 支持的事务管理类型
17、你在项目中是如何实现事务的?
18、@Transactional注解都有哪些属性?
19、什么是事务的传播行为?
20、有几种传播行为?
21、有几种隔离级别?
22、你刚才提到@Transactional注解有一个属性timeout,你是怎么理解的?
23、那属性readOnly你是如何理解并使用的?
一、Spring框架概述
1、什么是Spring?
答:spring的核心实现思想IOC,由spring来负责控制对象的生命周期和对象间的关系。注意以前对于一个类型(类),手动的使用new来实例化这个对象变量,现在不用你new了,交给spring控制。
在传统的开发中,在一个类定义另一个类的实例,这样的话,互相依赖,耦合在一起。spring的思想是两个类是独立的,用的时候在往里放,即轻松解耦。
2、spring优点有哪些?
答:可以从四个方面来答,解耦、切面、方便集成各种优秀框架、一站式。
一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上spring自身也提供了展现层的springmvc和持久层的spring JDBC),也就是说完全可以用一个spring技术就可以搭建一个web项目。
二、IOC与DI
3、你知道getBean方法的有几种重载方式吗?
答:三种
//第一种getBean(id):通过id去spring容器中找对象
Person person01 = (Person) ac.getBean("personOne");
//第二种getBean(类型):通过类型去spring容器中找对象
Person person02 = ac.getBean(Person.class);
//第三种getBean(id,类型):通过id + 类型去spring容器中找对象
Person person03 = ac.getBean("personTwo",Person.class);
4、Spring有几种依赖注入方式?
答:三种
分别是setter方式、构造器方式和P命名空间方式。
三、Spring创建对象
5、Spring创建对象有几种方式?
答:三种
分别是无参构造、静态工厂、实例工厂方式。
6、你简单说说Bean有哪些作用域?
答:Bean有四种作用域,分别是Singleton(默认的)、Prototype、Request、Session。
7、Bean的生命周期?
答:
Spring 容器根据配置中的 bean 定义中实例化 bean。
Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName()。
如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
如果存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法。
如果为 bean 指定了 init 方法( <bean> 的 init-method 属性),那么将调用它。
最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
如果为 bean 指定了 destroy 方法( <bean> 的 destroy-method 属性),那么将调用它。
四、注解
8、你使用过哪些Spring注解?
答:
- @Controller:一般用在控制层
- @Service:一般用在业务层
- @Repository:一般用在数据层
- @Component:可以用在各种类上
- @Resource:根据名称注入类,但注意此类是JDK的注解,并不是Spring的,只不过我们通常拿它和@Autowired一起比较
- @Autowired:用于在 spring bean 中自动装配,是根据类型注入类。
- @Scope:用于配置 spring bean 的作用域。
- @Aspect,@Before,@After,@Around,@Pointcut 用于切面编程(AOP)。
9、那@Controller、@Service、@Repository和@Component有什么区别?
答:虽然都用在各自的层(控制层、业务层、数据层)上,但其实本质没什么区别,哪怕你@Controller用在业务层,@Service用在数据层也不会出错,Spring是不会校验这个的,只不过我们这么写是为了让我们自己知道这个类是干什么的,哪个层,真正的意图是什么。
10、@Resource与@Autowired的区别?
答:
(1)来源不同:@Autowired 和 @Resource 来自不同的“父类”,其中 @Autowired 是 Spring 定义的注解,而 @Resource 是 Java 定义的注解,它来自于 JSR-250(Java 250 规范提案)。
(2)查找顺序不同:@Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找。而@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找。
五、面向切面编程(AOP)
11、什么是AOP?
答:AOP把重复的功能拿出来放到类中,让应用对象只关注于自己所针对的业务领域问题,而其他方面的问题由其他应用对象来处理。
举例:我们公司想要请明星做代言,明星跟我们洽谈工资、合同、以及租场地、演出,这些都是明星自己一个人干,那么这就不是切面编程。切面编程是让明星只关注于自己的业务领域(演出),其它的活可以交给经纪人(代理对象)去做。
12、AOP如何手动实现?
答:有两种方式,JDK动态代理和CGLIB,JDK动态代理必须是接口,而CGLIB没有接口,只有实现类。采用字节码增强框架cglib,在运行时创建目标类的子类,从而对目标类进行增强。
13、你在项目中是如何实现的?用过AspectJ吗?
答:用过
AspectJ是一个基于Java语言的AOP框架。
spring2.0以后新增了对AspectJ切点表达式的支持。
@AspectJ是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面。
新版本spring框架,建议使用AspectJ方式来开发AOP。
主要用途:自定义开发。
14、有哪些通知类型?
答:我知道有5种通知类型,分别是:
before:前置通知,应用于各种校验,在方法执行前执行,如果通知抛出异常,阻止方法运行。
afterReturning:后置通知,应用于常规数据处理,方法正常返回后执行,如果方法中抛出异常,通知无法执行。必须在方法执行后才执行,所以可以获得方法的返回值。
around:环绕通知,十分强大,可以做任何事情,方法执行前后分别执行,可以阻止方法的执行。必须手动执行目标方法。
afterThrowing:抛出异常通知,一般应用包装异常信息,方法抛出异常后执行,如果方法没有抛出异常,无法执行。
after:最终通知,一般用于清理现场环节,方法执行完毕后执行,无论方法中是否出现异常。相当于在finally代码块中。
六、JdbcTemplate
15、用过Spring自带的JDBC API技术JdbcTemplate吗?随便说几个常用的方法
答:当然用过,常用的方法有这几种:
增 update方法
删 update方法
改 update方法
批量增删改 batchupdate方法
查询实体 Bean queryForObject方法
查询 List query方法
查询 Map queryForMap方法
查询 List<Map<String,Object> queryForList方法
七、事务
16、列举spring 支持的事务管理类型
答:支持编程式事务管理和声明式事务管理。
使用原生的JDBC API进行事务管理类似于这样:
① 获取数据库连接Connection对象。
② 取消事务的自动提交。
③ 执行操作。
④ 正常完成操作时手动提交事务。
⑤ 执行失败时回滚事务。
⑥ 关闭相关资源。
使用原生的JDBC API实现事务管理是所有事务管理方式的基石,同时也是最典型的编程式事务管理。编程式事务管理需要将事务管理代码嵌入到业务方法中来控制事务的提交和回滚,在使用编程的方式管理事务时,必须在每个事务操作中包含额外的事务管理代码。相对于核心业务而言,事务管理的代码显然属于非核心业务,如果多个模块都使用同样模式的代码进行事务管理,显然会造成较大程度的代码冗余。
17、你在项目中是如何实现事务的?
答:使用@Transactional注解实现事务,可以作用在类和方法上。
18、@Transactional注解都有哪些属性?
答:常用的共有四种,分别是propagation(传播行为)、isolation(隔离级别)、timeout(超时操作)、readOnly(是否只读)。
19、什么是事务的传播行为?
答:A方法和B方法都有事务,当A在调用B时,会将A中的事务传播给B方法,B方法对于事务的处理方式就是事务的传播行为。
20、有几种传播行为?
答:七种,分别是required(默认)、supports、mandatory、requires_new、not_supported、never、nested。
21、有几种隔离级别?
答:读未提交、读已提交、可重复读、串行化。
22、你刚才提到@Transactional注解有一个属性timeout,你是怎么理解的?
答:情景:假如说京东秒杀活动,有1万个请求同时执行,这时有1000个请求在某个步骤上卡住了,那么你如果没有设置超时时间,请求会一直卡在那。因为我们知道一个连接对象要么提交要么回滚才算一个事务执行完毕。如果设置了超时时间假如说是5秒,那么就会等待5秒后还没有提交事务的话就直接强制回滚。这样的话也就释放连接了。
23、那属性readOnly你是如何理解并使用的?
答:指定当前事务中的一系列的操作是否为只读。若设置为只读,mysql就会在请求访问数据的时候不加锁,提高性能。
问题:如果一个事务内既有读也有修改操作,那么可以设置readOnly="true"吗?
可以设置,但是没什么用,反而变麻烦了,假如你设置了true,并且事务中有了修改操作。那么就会让所有的操作都不加锁,这样的话会造成脏读、幻读、不可重复读都来了。所以只有你这个事务内全部都是读的操作,才能加上readOnly="true"。