Spring系列一.知识点

1.什么是spring?

Spring是一个2003年兴起的轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。

控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。

框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你

2.spring有什么作用?

1.方便解耦,简化开发

2.AOP编程

3.事务支持

4.集成框架

3.什么是控制反转(IOC)?

IoC(Inversion of Control,控制反转)

通过反射机制生成对象注入

是一种解耦的设计思想, Spring IOC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。 IOC 容器负责创建对象,将对象连接在一起,配置这些对象,并从创建中处理这些对象的整个生命周期,直到它们被完全销毁。

DI(Dependecy Inject,依赖注入)是实现控制反转的一种设计模式,依赖注入就是将实例变量传入到一个对象中去。

4.什么是面向切面(AOP)编程?

Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理,也可以使用 AspectJ ,Spring AOP 已经集成了AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。

可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善, 它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。

能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,需要用到的地方直接使用即可, 便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

5.Spring AOP 和 AspectJ AOP 有什么区别?

Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。

如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比Spring AOP 快很多。

6.JDK Proxy 和 Cglib Proxy 有何区别?

自Java 1.3以后,Java提供了动态代理技术

JDK动态代理主要涉及java.lang.reflect包下边的两个类:ProxyInvocationHandler。其中,InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑编织在一起。

JDK动态代理的话,他有一个限制,就是它只能为接口创建代理实例

CGLib采用底层的字节码技术,全称是:Code Generation Library,CGLib可以为一个类创建一个子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。

7.JDK Proxy实现?

需要一个接口

需要一个InvocationHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
InvocationHandler hander = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
if(method.getName().equals("b")) {
System.out.println("你好:"+args[0]);
}
return null;
}
};

// 传入 加载器
// 传入代理接口
// 传入 hander
A a = (A) Proxy.newProxyInstance(A.class.getClassLoader(), new Class[] {A.class}, hander);
a.b("zhw");
}

8.CGlib Proxy实现?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
Enhancer eh = new Enhancer(); // Enhancer是CGlib得一个类和Java1.3动态代理中引入的Proxy类差不多
eh.setSuperclass(B.class);
eh.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println(method);
System.out.println("前 ");
Object js = proxy.invokeSuper(obj, args);
System.out.println("后 ");
return js; // 对象 参数
}
});
B b = (B) eh.create();
b.bb("zwh");
}

9.spring事物?4大特性 4大隔离级别 7大传播行为

事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.

事务特性:ACID 4种

原子性 (atomicity):强调事务的不可分割.
一致性 (consistency):事务的执行的前后数据的完整性保持一致.
隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰
持久性(durability) :事务一旦结束,数据就持久到数据库

如果不考虑隔离性引发安全性问题:
脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
虚读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.

事务隔离级别:4种

未提交读(read uncommited) :脏读,不可重复读,幻读都有可能发生
已提交读 (read commited):避免脏读。但是不可重复读和幻读有可能发生
可重复读 (repeatable read) :避免脏读和不可重复读.但是幻读有可能发生.
串行化的 (serializable) :避免以上所有读问题.
Mysql 默认:可重复读
Oracle 默认:读已提交

事务传播行为:7种

保证同一个事务中
propagion_required: 支持当前事务,如果不存在 就新建一个(默认)
propagion_supports: 支持当前事务,如果不存在,就不使用事务
propagion_mandatory: 支持当前事务,如果不存在,抛出异常

保证没有在同一个事务中
propagion_requires_new: 如果有事务存在,挂起当前事务,创建一个新的事务
propagion_not_supported: 以非事务方式运行,如果有事务存在,挂起当前事务
propagion_never: 以非事务方式运行,如果有事务存在,抛出异常
propagion_nested: 如果当前事务存在,则嵌套事务执行

10.声明式事务和编程式事务的区别?

声明式事务优先于编程式事务,声明式事务可以回滚事务

@Transactional(rollbackFor = { Exception.class })

1
2
3
4
@Transactional
public Map<String, Object> fun() {

}

编程式事务

手动开启、提交、回滚事务

定义事务规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

public class Utils {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;

// 开启事务
public TransactionStatus openTx() {
return dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
}
// 提交事务
public void commitTx(TransactionStatus ts) {
dataSourceTransactionManager.commit(ts);
}
// 回滚事务
public void rollbackTx(TransactionStatus ts) {
dataSourceTransactionManager.rollback(ts);
}

使用定义的事务规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try {
// 开启事务
ts = utils.openTx();
registerMapper.programming( name, age, studentId);
int a=1/0;
registerMapper.programming( name, age, studentId);
if (ts != null) {
// 提交事务
utils.commitTx(ts);
}
} catch (Exception e) {
if (ts != null) {
// 回滚事务
utils.rollbackTx(ts);
}
}

11.spring常用注解?

几种比较重要的注解类型:

1.@Required:该注解应用于设值方法。

2.@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。

3.@Qualifier:该注解和@Autowired 注解搭配使用,用于消除特定 bean 自动装配的歧义。

4.JSR-250 Annotations: Spring 支持基于 JSR-250 注解的以下注解,@Resource、 @PostConstruct 和 @PreDestroy。

注册:@Controller @Service @Component

注入:@Autowired

请求地址:@RequestMapping

返回具体数据类型而非跳转:@ResponseBody

小唠嗑:

本章到这里就结束了,谢谢耐心看到这里的各位Boss,如果觉得有哪里说的不好的地方,还请高抬贵手多多原谅,不惜指教。

最后,谢谢!

---本文结束感谢您的阅读!---

本文标题:Spring系列一.知识点

文章作者:周宏伟

发布时间:2020年08月05日 - 21:08

最后更新:2020年08月06日 - 18:08

原始链接:http://oldzhoua.github.io/2020/08/05/Spring系列一-知识点/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。