Spring:是Java企业级应用的开源开发框架。
IOC和DI
IOC:控制反转
也就是使用了spring之后,对象的创建方式从我们自己创建反转给了程序创建(spring)
DI:依赖注入
组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)
实现IOC思想需要DI做支持
注入方式:set方式注入、构造方法注入、字段注入
注入类型:值类型注入、引用类型注入
ApplicationContext接口
- 每次容器启动时就会创建容器中配置的所有对象
- 从类路径下加载配置文件:ClassPathXmlApplicationContext
- 从硬盘的绝对路径下加载配置文件:FileSystemXmlApplication
Spring配置
bean元素
- name属性:给被管理的对象起个名字,获得对象时getBean(“name值”);
- class属性:被管理对象的完整类名
- id属性:与name属性一摸一样,名称不可重复,不能使用特殊字符
- scope属性:默认值singleton(单例):在spring容器中只会存在一个实例;prototype(多例):每次在获得才会被创建
三种创建方式
- 构造方式
<!-- 1. 默认无参数构造器 -->
<bean id="user1" class="com.nwpu.geeker.User"></bean>
<!-- 2. 带参数构造器 -->
<bean id="user2" class="com.nwpu.geeker..User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
</bean>
- 工厂类创建对象
<!-- 3.1 工厂类,实例方法 -->
<!-- 先创建工厂 -->
<bean id="factory" class="com.nwpu.geeker.ObjectFactory"></bean>
<!-- 在创建user对象,用factory方的实例方法 -->
<bean id="user4" factory-bean="factory" factory-method="getInstance"></bean>
<!-- 其中: factory-bean=”factory”指定工厂。factory-method=”getInstance”指定工厂的哪个方法。 -->
- 静态方法创建
<bean id="user" class="com.nwpu.geeker.ObjectFactory" factory-method="getStaticInstance"></bean>
<!-- class 指定的就是工厂类型,这里是和上面配置不同的地方。factory-method 一定是工厂里面的“静态方法” -->
细节问题:
是否延迟创建 :
lazy-init=”false” 默认为false, 不延迟创建,即在启动时候就创建对象
lazy-init=”true” 延迟初始化, 在用到对象的时候才创建对象
创建对象之后,初始化/销毁 :
init-method=”init_user” 【对应对象的init_user方法,在对象创建好之后执行 】
destroy-method=”destroy_user” 【在调用容器对象的destroy方法时候执行,(容器用实现类)】
Spring常用的三种注入方式
构造方法注入
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
<!-- 如果想向多个参数构造方法中注入值 -->
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<constructor-arg name="userDao" ref="userDaoJdbc"></constructor-arg>
<constructor-arg name="user" ref="user"></constructor-arg>
</bean>
setter注入
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<!-- 写法一 -->
<!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
<!-- 写法二 -->
<property name="userDao" ref="userDaoMyBatis"></property>
</bean>
<!-- 注册mybatis实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>
- 注意:
- 上面这两种写法都可以,spring会将name值的每个单词首字母转换成大写,然后再在前面拼接上”set”构成一个方法名,然后去对应的类中查找该方法,通过反射调用,实现注入
- name属性值与类中的成员变量名以及set方法的参数名都无关,只与对应的set方法名有关
- 如果通过set方法注入属性,那么spring会通过默认的空参构造方法来实例化对象,所以如果在类中写了一个带有参数的构造方法,一定要把空参数的构造方法写上,否则spring没有办法实例化对象,导致报错
注解注入
前提:
bean属性autowire:三个属性值:constructor,byName,byType
- constructor:通过构造方法进行自动注入,spring会匹配与构造方法参数类型一致的bean进行注入
- byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。
- byType:查找所有的set方法,将符合符合参数类型的bean注入
进入正题:
主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:
- @Component:可以用于注册所有bean
- @Repository:主要用于注册dao层的bean
- @Controller:主要用于注册控制层的bean
- @Service:主要用于注册服务层的bean
描述依赖关系主要有两种:
- @Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。
- @Autowired:spring注解,默认是以byType的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byName的方式去查找,
虽然有这么多的注入方式,但是实际上开发的时候自己编写的类一般用注解的方式注册类,用@Autowired描述依赖进行注入,一般实现类也只有一种(jdbc or hibernate or mybatis)
事务
ACID原则:
原子性:事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性:一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
隔离性:多个业务可能操作同一个资源,防止数据损坏
持久性:事务一旦提交,无论系统发生什么问题,结果都不会在被影响,被持久化的写到存储器中!
spring中事务可以分为编程式事务控制和声明式事务控制。
//自己手动控制事务,就叫做编程式事务控制。
//Jdbc代码:
Conn.setAutoCommit(false); // 设置手动控制事务
//Hibernate代码:
Session.beginTransaction(); // 开启一个事务
//Spring提供了对事务的管理, 这个就叫声明式事务管理。
//Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,
//只需要在配置文件中配置即可; 不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。
//Spring声明式事务管理,核心实现就是基于Aop。
//【粗粒度的事务控制: 只能给整个方法应用事务,不可以对方法的某几行应用事务。】
//(因为aop拦截的是方法。)
//Spring声明式事务管理器类:
// Jdbc技术:DataSourceTransactionManager
//Hibernate技术:HibernateTransactionManager