spring
一、介绍
spring负责管理项目中所有对象
分层的一站式框架
二、概念
思想
IOC: 反转控制 对象的创建以及依赖关系可以由spring完成创建以及注入
DI: 依赖注入 实现IOC思想需要DI做支持
注入方式:
set方法注入 构造方法注入 字段注入
注入类型:
值类型注入 引用类型注入
BeanFactory接口实现类的容器,特点是每次在获得对象时才会创建对象。
ApplicationContext每次容器启动时就会创建容器中配置的所有对象。并提供更多功能。
三、配置详解
注册对象 <bean/> name属性:根据名称获得对象 id:除了不可重复且不能使用特殊字符外其他与name属性相同 class:被管理对象的完整类名
三种对象创建方式
1、走空参构造
2、静态工厂 spring调工厂中的静态方法来创建
<bean name="" class="" factory-method="要调用的方法名"></bean>
3、实例工厂 方法是实例方法 配置需要两个bean(方法不是静态的,需要先创建工厂对象,通过工厂对象来调用)
<bean name="" factory-bean="" factory-method=""></bean>
把工厂配置成一个bean <bean name="" class=""></bean>
bean元素进阶 scope属性
singleton(默认值):单例对象 在spring容器中只会存在一个对象
prototype:多例 每次获得时才会创建 每次创建都是新的对象
不使用:{request:web环境下 与request声明周期一致
session:web环境下,对象与session生命周期一致}
生命周期属性
配置生命周期初始化方法 init-method=""
配置生命周期销毁方法 destory-method="" 在执行之前虚拟机就关闭了 需要使用ApplicationContext的实现类ClassPathXmlApplicationContext中的close方法把容器关闭掉才能执行。
模块化配置 导入其他配置文件 <import resource="">
四、属性注入
set方法注入
值类型注入 <property name="" value=""></property>
引用类型注入<property name="" ref="引用的bean的name"></property>
p名称空间 实际走的还是set方法注入
值类型:p:属性名= "值"
对象类型: p:属性名-ref = "bean名称"
构造函数注入
<construct-arg name="" value="" ></construct-arg>属性还有index,type
spel注入
<property name="" value=""></property>
value="#{user.name}" 取别的bean的value(值类型)
ref="bean的名称" 引用类型依然这样写
复杂类型注入
数组类型 如果数组中只准备注入一个值,直接使用value/ref即可
多个 <property>
<array>
<value></value>
<value></value>
<ref bean=""/ >
</array>
</property>
list/set类型 如果只准备注入一个值,直接使用value/ref即可
<list><value></value><ref bean=""/></list>
map类型
键为字符串,值为字符串。<entry key="url" value="jdbc:mysql:///crm"></entry>
键为字符串,值为对象。<entry key="user" value-ref="user4"></entry>
键为对象,值为对象。<entry key="user3" value-ref="user2"></entry>
properties
使用注解配置spring
扫描包下的所有类的注解
<context:component-scan base-package=""></context>
@Component("user")代替注册对象
@Service("user")
@Controller("user")
@Repository("user")这四个都能用,后三个体现分层
@Scope(scopeName="prototype")
@Value("tom") @Value("tom")
private String name; 或 public void setName(String name){this.name=name;}
通过反射的field赋值(破坏了封装性) 通过set赋值
@Autowired自动装配 如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象
所以加上@Qualifier("car2")使用Qualifier注解告诉spring容器自动装配哪个名称的对象
或者直接用@Resource(name="car2")(推荐)
@PostConstruct 对象创建后调用(init-method)
@PreDestroy 在销毁之前调用(destory-method)(singleton才会有容器管理的完整生命周期,多例模式不会调用此方法)
四、aop
面向切面的思想 如拦截器(设置所有servlet的字符编码)
spring整合了动态代理(必须有接口)和cglib代理
连接点:目标对象中,所有可以增强的方法。
切入点:目标对象,已经增强的方法。
通知/增强:增强的代码
目标对象:被代理对象
织入:将通知织入切入点
代理:将通知织入切入点后形成的代理对象
spring aop配置
配置目标对象 配置bean
配置通知对象 配置bean
配置切入点
<aop:config>
<aop:pointcut expression="" id="">
<aop:aspect ref="myAdvice">引用通知对象
<aop:before method="" point-ref="">
</aop:aspect>
</aop:config>
前置通知 <aop:before method="" point-ref="">
后置通知(如果方法出现异常,不会调用)<aop:after-returning method="" point-ref="">
环绕通知(需要传一个ProceedingJoinPoint对象,通过该对象的proceed方法手动调用要执行的方法)<aop:around method="" point-ref="">
异常通知(在异常出现之后)<aop:after-throwing method="" point-ref="">
后置通知(出现异常也会调用)<aop:after method="" point-ref="">
注解配置
@Aspect 表示该类是一个通知类
@Before("execution(*cn.itcast.service.*ServiceImpl.*(..))")
@AfterReturning("execution(*cn.itcast.service.*ServiceImpl.*(..))")
@Around("execution(*cn.itcast.service.*ServiceImpl.*(..))")
@AfterThrowing("execution(*cn.itcast.service.*ServiceImpl.*(..))")
@After("execution(*cn.itcast.service.*ServiceImpl.*(..))")
也可以省略表达式 单独写
@Pointcut("execution(*cn.itcast.service.*ServiceImpl.*(..))")
public void pc(){}
@Before("MyAdvice.pc()")
五、整合JDBC
spring提供了一个可以操作数据库的对象。对象封装了jdbc技术
与DBUtils的QueryRunner非常相似
需要导入c3p0连接池 JDBC驱动 spring-tx spring-jdbc
ComboPooledDataSource dataSource = new ComboPooledDataSource ();
dataSource.setDriverCLass("..........");
dataSource.setJdbcUrl("..........");
dataSource.setUser("........");
dataSource.setPassword(".........");
---------------------------------------------------------------或者使用配置文件进行设置
JdbcTemplate jt = new JdbcTemplate();
jt.setDataSource(dataSource);
String sql = "..........";
jt.update(sql);
整合jdbc-连接池JDBC模板
1.将连接池放入spring容器
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="jdbc:mysql:///hibernate_32">
<property name="driverClass" value="..................">
<property name="user" value="...........">
<property name="password" value="..........">
</bean>
--------------------------由于以上属性经常要改,所以单独放在一个properties中
配置变为
<context:property-placeholder location="classpath:db.properties">
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.jdbcUrl}">
<property name="driverClass" value="">
<property name="user" value="...........">
<property name="password" value="..........">
</bean>
2.将JDBCTemplate放入spring容器
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource">
</bean>
也可以让daoImpl继承JDBCDaoSupport(根据连接池创建JDBC模板,无需自己获取)
该类中有getJdbcTemplate()方法,有dataSource属性
用不用JDBCDaoSupport都无所谓,能少一层关系,无需配置JDBCTemplate
需要在daoImpl的bean中注入dataSource替代模板对象注入
六、事务管理
在不同平台,操作事务的代码各不相同。spring提供了一个接口。
PlatformTransactionManager
管理事务的属性介绍
事务的隔离级别
读未提交
读已提交
可重复读
可串行化
是否只读
true false
事务的传播行为
一个方法里调用另一个service的方法
PROPAGATION_REQUIRED 支持当前事务,如果不存在,就新建一个(一般用这个)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_HANDATORY 支持当前事务,如果不存在,抛出异常
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 如果当前事务存在,则嵌套事务运行
spring管理事务方式
编码式
事务核心管理器。封装了所有事务操作,依赖于连接池
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTranctionManager">
<property name="dataSource" ref="dataSource"> </property>
</bean>
service中注入transactionTemplate
AccountServiceImpl
private AccountDao ad;
private TransactionTemplate tt;
public void .....(........................){
tt.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0){
//其封装好了打开和关闭事务的操作,纳入事务的操作写在这里即可
}
});
}
xml配置aop事务
配置事务通知
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="需要纳入事务中的方法(可以使用通配符)" isolation="隔离级别" propagation="传播行为" read-only=""true/false />
</tx:attributes>
</tx:advice>
配置织入(将通知织入所有符合切点的所有类,并进一步判断方法的事务属性)
<aop:config>
配置切点表达式
<aop:pointcut expression="execution(....................)" id="txPc"/>
配置切面(通知+切点=切面)
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>
注解配置

浙公网安备 33010602011771号