spring 简答
yuiyake 5/14/2021
# spring
# 整体架构
#
# 核心容器
Beans,创建和管理bean以及ioc,访问配置文件等
- ioc:即控制反转。解释“构成应用程序主干并由springioc容器管理的对象成为bean。 bean是由springioc容器实例化,组装和管理的对象,他们是springioc容器的基础。
- DI:即依赖注入(应用依赖于ioc容器,ioc容器把小的外部资源注入进应用依赖的某个对象。)
- Core,核心工具类,是其它组件的基本核心,我们也可以自己使用。
- Context,构建于core和beans模块基础之上,为spring核心提供扩展,它的关键是ApplicationContext接口,添加了bean的生命周期控制等功能。
- Expression Language, 提供强大的表达式语言,用于在运行时查询和操纵对象。
# 依赖注入
- 定义 依赖注入 指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部的注入。
构造方法注入
- 优点
- 脱离了ioc框架这个类仍然可以工作(POJO)
- 缺点
- 参数过多
- 一旦是用构造函数注入,就无法是用默认构造函数(比如MVC框架的Controller类)
- 有冗余方法并不需要依赖
public class StupidStudent { private SmartStudent smartStudent; public StupidStudent(SmartStudent smartStudent) { this.smartStudent = smartStudent; } public doHomewrok() { smartStudent.doHomework(); System.out.println("学渣抄作业"); } } public class StudentTest { public static void main(String[] args) { SmartStudent smartStudent = new SmartStudent(); StupidStudent stupidStudent = new StupidStudent(smartStudent); stupidStudent.doHomework(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17- 优点
setter方法注入
- 优点
- 在对象的生命周期内,可以动态改变依赖,灵活。
- 缺点
- 不直观
public class StupidStudent { private SmartStudent smartStudent; //添加setter方法 public void setSmartStudent(SmartStudent smartStudent) { this.smartStudent = smartStudent; } public doHomewrok() { smartStudent.doHomework(); System.out.println("学渣抄作业"); } } public class StudentTest { public static void main(String[] args) { SmartStudent smartStudent = new SmartStudent(); StupidStudent stupidStudent = new StupidStudent(); stupidStudent.setSmartStudent(smartStudent); stupidStudent.doHomework(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19- 优点
接口注入
- 优点
- 灵活
- 缺点
- 参数过多
- 新加入依赖时会破坏原有方法名
public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... }
1
2
3
4
5
6
7
8
9
10
11
12- 优点
# 封装模块
- jdbc,用jdbc数据访问进行封装类
- orm,对象-关系映射api
- oxm, 对object/xml映射实现抽象层
- jms, messagingService制造和消费信息的特性
- Transaction, 支持变成和声明性的事务管理
# AOP
AOP实现策略:
- JavaSE动态代理
- 字节码生成(cglib)
- 定制的类加载器
- 代码生成
- 语言扩展
aop核心,面向切面
aspects, 用AspectJ框架
instructment, 可以通过代理类在运行时修改的字节,从而改变一个类的功能,实现AOP
三种织入方式
- 编译器织入 -- 要有特殊java编译器
- 类装载期织入 -- 要有特殊类装载器
- 动态代理织入 -- 在运行期间为目标添加通知生成子类 tips:Spring AOP框架默认动态代理织入,而AspectJ采用编译器和类装载期织入
Spring AOP增强类型:
- 前置增强
- 后置增强:无论方法是正常执行完还是抛出异常都会执行此增强
- 返回后增强
- 抛出异常后增强
- 环绕增强:包围连接点方法的增强,可替代前述任何一种增强
- 引介增强:能使目标类实现某个接口
# ✨书本上的课后习题(个人觉得有意义/不会的)
控制反转(IOC)和依赖注入(DI)是什么?优点?
- ioc是一种设计思想,意味着将设计好的对象给容器控制,非直接由对象控制。
- Spring中实现控制反转的是IoC容器,其实现方法是依赖注入。
- 优点 解耦手段。
IOC容器的实现方式有哪些?
- 构造方法注入
private TestDIDaoo testDIDaoo; public TestDiServiceImpl(TestDao) { super(); this.testDiDao = testDIDaoo; } //配置 <bean id="myTestDIDao" class="dao.TestDIDaoImpl" /> <bean id="testDIService" class="service.TestDIServiceImpl"> <constructor-arg index="0" ref="myTestDIDao"> </bean>
1
2
3
4
5
6
7
8
9
10 - setter注入*** 注 spring的依赖注入都是通过反射机制实现。
private TestDIDao testDDIDao; public void setTestDIDao(TestDIDao testDIDao) { this.testDIDao = testDIDao; } //配置 <bean id="testDIServicel" class="serice.TestDIServiceImpl1"> <property name="testDIDao" ></property> </bean>
1
2
3
4
5
6
7
8
- 构造方法注入
bean实例化的常见方法?(第三章)
- 构造方法实例化
- 静态工厂实例化
- 实例工厂实例化
简述基于注解的装配方式的装配方法
- 1创建bean实现类
@Conponent() public class AnnotationUser { @Value("chenheng") private String uname; }
1
2
3
4
5- 2配置注解
//配置注解 <context:component-scan base-package="bean所在的包路径">
1
2- 3测试实例
main{ ApplicationContext appCon = new ClassPathXmlApplicationContext("annotationContext.xml"); AnnotationUser au = (AnnotationUser)appCon.getBean("annotationUser"); Sysout(au.getUname()); }
1
2
3
4
5@Autowired和@Resource的区别?
- auto的默认是byType,但当byType有多个时,会用byName;resource的默认是byName,如果找不到指定的name,会用byType.
bean的默认作用域?
- singleton,这个定义的bean在spring容器中只有一个bean实例
什么是AOP?AOP术语?(第四章)
- aop,即面向切面编程,在aop中的基本单元是aspect(切面)。采取横向抽取机制, 将分散在各个方法中的重复代码提取出来,在程序编译运行阶段织入。
- aop术语:
- 切面
- 连接点
- 切入点
- 通知
- 引入
- 目标对象
- 代理
- 织入
java中有哪些常用的动态代理技术?
- JDK动态代理
public class JDKDynamicProxy implements InvocationHandler { //声明目标类接口对象(真实对象) private TestDao testDao; //创建代理的方法,建立代理对象和真实对象的代理关系,并返回代理对象 public Object createProxy(TestDao testDao){ this.testDao = testDao; //类加载器 ClassLoader cld = JDKDynamicProxy.class.getClassLoader(); //被代理对象实现的所有接口 Class[] clazz = testDao.getClass.getInterfaces(); //使用代理类进行增强,并返回代理后的对象 return Proxy.newProxyInstance(cld, clazz, this); } // @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //创建一个切面 MyAspect myAspect = new MyAspect(); //前增强 myAspect.check(); myAspect.except(); //在目标类上调用方法并传参,相当于调用testDao中的方法 Object obj = method.invoke(testDao, args); //后增强 myAspect.log(); myAspect.monitor(); return obj; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 - CGLIB动态代理
public class CglibDynamicProxy implements MethodInterceptor{ public Object createProxy(Object target){ //创建一个动态类对象(增强类对象) Enhancer enhancer = new Enhancer(); //确定要增强的类 enhancer.setSuperclass(target.getClass()); //确定代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor的方法 enhancer.setCallback(this); //返回创建的代理类对象 return enhancer.create(); } @Override public Object intercept(Object proxy, Method method, Object[] args) { //创建一个切面 MyAspect myAspect = new MyAspect(); //前增强 myAspect.check(); myAspect.except(); //在目标类上调用方法并传参,相当于调用testDao中的方法 Object obj = method.invoke(testDao, args); //后增强 myAspect.log(); myAspect.monitor(); return obj; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26- JDK动态代理
AspectJ框架的AOP开发方式有几种?
- 基于xml配置开发
- 基于注解开发
什么是编程式事务管理?在Spring中有哪几种编程式事务管理?(第五章)
- 代码中显示调用beginTransaction、commfit、rollback等于事务处理相关的方法就是编程式事务管理。
- 有种事务管理
- 基于底层api的事务管理
public interface PlatformTransactionManager{ TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;//定义符合Spring的事务属性的接口 void commit(TransactionStatus status) throws TransactionException;//事务状态的表示 void roolback(TransactionStatus status) throws TransactionException;//应用程序开发人员可以选择捕获和处理 }
1
2
3
4
5 - 基于TransactionTemplate的编程式事务管理
transactionTemplate execute(new TransactionCallback() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperaction1(); updateOperaction2(); } catch(SomeBusinessException ex) { status.setRollbackOnly(); } } })
1
2
3
4
5
6
7
8
9
10 - 基于底层api的事务管理
简述声明式事务管理的处理方式。
xml声明式事务管理
@Transactional注解声明式事务管理
Spring Framework中有几个模块?作用是?
Spring 核心容器
该层基本上是 Spring Framework 的核心。它包含以下模块:
- Spring Core
- Spring Bean
- SpEL (Spring Expression Language)
- Spring Context
数据访问/集成 – 该层提供与数据库交互的支持。它包含以下模块:
- JDBC (Java DataBase Connectivity)
- ORM (Object Relational Mapping)
- OXM (Object XML Mappers)第 367 页 共 485 页
- JMS (Java Messaging Service)
- Transaction
Web
该层提供了创建 Web 应用程序的支持。它包含以下模块:
- Web
- Web – Servlet
- Web – Socket
- Web – Portlet
AOP
该层支持面向切面编程
Instrumentation
该层为类检测和类加载器实现提供支持。
Test
该层为使用 JUnit 和 TestNG 进行测试提供支持。
几个杂项模块:
Messaging
- 该模块为 STOMP 提供支持。它还支持注解编程模型,该模型用 于从 WebSocket 客户端路由和处理 STOMP 消息。
Aspects
- 该模块为与 AspectJ 的集成提供支持。
spring 中有多少种 IOC 容器?
- BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端 要求时实例化 bean。
- ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。它 在 BeanFactory 基础上提供了一些额外的功能。
注解
- @Service用于标注业务层组件
- @Controller用于标注控制层组件(如struts中的action)
- @Repository用于标注数据访问组件,即DAO组件
- @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。