spring原理入门

Spring架构初解

这里只记录一些常用的
beans:放着BeanFactory等读取解析配置文件并通过反射实例化对象的代码
core:核心工具类,被所有其它包调用的包
AOP:为spring提供简单的AOP功能
Aspects:外部的AOP,更加细致的AOP使用
ORM:提供记录和对象的映射,为了更方便地操作从数据库获得的记录
JDBC:JDBC是一套Java对数据库的标准,而Spring封装了它,形成了自己的JDBC库
Transaction:提供了事务

Bean与容器

简单的流程

将bean所在文件(JavaConfig,xml,注释)装起来(classPathResource)
(ApplicationContext)容器使用读取器(Reader)解析bean
加载bean(生命周期)到容器

IOC与DI

IOC的意思是控制反转,原来如果一个对象需要另一个对象,那么它会去new一个对象,然后根据自己需要初始化对象,如果不需要了,就把这个对象给赋值null(help GC),现在这些操作全部交给容器了,对象只负责从容器里获取这个对象来用,将对这个对象的很大部分操作都交给容器完成,也就是把主控制权交给容器
DI的意思是依赖注入,也就是在需要对象的地方,只要注明了,容器就会把对象塞到这个变量中。

Bean的装配

以下代码只作理解用,请不要在意bug

xml型配置

1 创建对象

package com
public class A{
	public String name;
	public String no;
	public A(){}
	public A(String name){this.name = name;}
	public void setNo(){
	 	this.no = no;
	 }
}

2 在xml中配置属性

<xml .........>
	<bean id = "test" class = "com.A">
		<!-- constructor-args可省略,省略默认调用无参构造,不省略就会根据找到的
		constructor-args集合起来,寻找一个参数相同的有参构造器 -->
		<constructor-args name="name" value="小李"></constructor-args>
		<!-- 以下这行通过对象中set方法给属性赋值 -->
		<property name ="no" value="10086"></property>
	</bean>
</xml>

3 读取xml到容器,将bean装配到属性里

class B{
	A a;
	Application context;
	public B{
		context = new ClassPathXmlApplicationContext("as.xml");
		//根据名字查找bean
		A a = context.getBean("test",A.class);
	}
}

JavaConfig型配置(SpringBoot使用)

1 创建对象

package com
//从以下四个任选其一,效果都是一样的,value相当于bean id
@Component(value="test")
//@Service
//@Repository
//@Controller
public class A{
	//这个相当于bean的property,但是不需要set方法
	@Value(value="hello")
	public String name;
	public String no;
	public A(){}
	public A(String name){this.name = name;}
	public void setNo(){
	 	this.no = no;
	 }
}
package com
//这个类不注解
public class B{
	public String name;
	public B(String name){this.name = name;}
}

2 在JavaConfig中配置bean

@Configuration
<!-- 这个注解可以用于扫描组件-->
@ComponentScan(base Package="com")
public class config{
	//这个注解创建出来的Bean,id就是这个方法名,也可以通过name自己指定bean id
	@Bean
	public B b(){
		return new B("abc");
	}
}

3 读取Configuration到容器,将bean装配到属性里

class C{
	//这三个都能完成自动装配,第一个是用id查找,第二个是用类型查找。
	//第三个是Java自己的,Spring不推荐,同时支持id和类型
	@Qualified(name="test")
	//@Autowired 
	//@Resource
	A a;
	
	@Autowired
	B b;
}

p命名空间型

是xml型变种,不重要,知道有即可

Bean的生命周期

1 如果允许循环依赖,创建BeanFactory,将其加入缓存中
2 属性注入
3 调用相关Aware接口(用于取出上下文的东西到对象成员,如beanId或BeanFactory)
4 调用后置处理器的前置方法
5 调用init-Method,init-Method只能是写在该类里的方法
6 调用后置处理器的后置方法
7 正常运行
8 容器关闭或者调用自定义的destroy()

Spring解决循环依赖

Singleton时构造方法导致

class A{
	B b;
	public A(B b){
		this.b = b;
	}
}
class B{
	C c;
	public B(C c){
		this.c = c;
	}
}
class C{
	A a;
	public C(A a){
		this.a = a;
	}
}

存在当前创建bean池,如果构造方法相互依赖,会在池中发现自己,然后报BeanCurrentlyInCreationException
如A创建bean发现需要B,加入池并创建B的bean,B发现需要C,把自己加入池,C需要A时,发现A已经在池就会报错

Singleton时set方法导致

class A{
	B b;
	public void setB(B b){
		this.b = b;
	}
}
class B{
	C c;
	public void setC(C c){
		this.c = c;
	}
}
class C{
	A a;
	public void setA(A a){
		this.a = a;
	}
}

当完成构造方法构造bean时,就会在缓存中保存未完成注入的Object,这样其它类就可以直接通过get()获得,所以不会导致循环依赖

prototype作用域

直接禁止依赖注入,从而防止循环依赖

事务

属性配置

事务的传播性:
@Transactional(propagation=Propagation.REQUIRED)
事务的隔离级别:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
只读:
@Transactional(readOnly=true)
该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。
事务的超时性:
@Transactional(timeout=30)
回滚:
指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

传播等级

Propagation.REQUIRED 如果外层有事务,使用外层的事务。否则自建事务。
Propagation.REQUIRED_NEW 无论如何都会新建事务
Propagation.SUPPORTED 不会新建事务,但是支持外层事务
Propagation.NOT_SUPPORTED 不会新建事务,会挂起外层事务执行
Propagation.NEVER 不会新建事务,外层有事务直接报错
Propagation.MANDATORY 不会新建事务,外层没有事务直接报错
Propagation.NESTED 增加一个回滚点,如果内层有报错,并且异常在回滚范围内,就会在该点回滚而不会回到初始状态

隔离机制

和mysql相同

失效情况

数据库不支持事务
没有注册进容器
内部自调用导致事务拦截方法没有生效
事务方法不是public级
指定的异常类没有包含报出的异常(默认为RunTimeException)

参考

《Spring源码深度解析》
事务 https://www.cnblogs.com/mseddl/p/11577846.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值