一、spring是什么?
开源,分层,一站式,轻量级
二、 spring 核心
1、 ioc & di
2、aop
3、事务管理 (jdbc Template)
4、spring mvc (& webFlux :web框架)
三、IOC 控制反转
spring ioc容器(bean工厂(底层反射)---简单工厂模式(不是用反射))
通俗:ioc就是在spring 有一个bean 工厂,专门维护bean对象
四、如何告诉spring bean工厂生产什么样的bean?
方式一:基于XML的配置
1)<bean >属性
id/name
class
方式二:注解
1)开启注解功能
2) 开启扫描 <context:component-scan base-package=""/>
3)@Component @Value @Autowired
方式三:基于Java的配置
@Configuration + @Bean 取代xml配置
五、如何从spring bean工厂中获取bean
方式一: BeanFactory 懒加载
getBean(id) 推荐
getBean(类名.class) 推荐
getBean(类的全限定名)
getBean(id,类的全限定名)
getBean(类名.class,类的全限定名);
方式二:ApplicationContext 及时加载
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
方式三:WebApplicationContext
总结:BeanFactory 与ApplicationContext区别:
1)ApplicationContext接口继承了BeanFactory.
2)BeanFactory在使用到getBean()方法的时候才会加载(实例化)这个类对象.
ApplicationContext接口加载配置文件的时候,创建所有的类对象 .
3)ApplicationContext对BeanFactory提供了扩展:
* 国际化处理
* 事件传递
* Bean自动装配
* 各种不同应用层的Context实现
***** 早期开发使用BeanFactory.
六、DI : Dependecy Injection 依赖注入
1、set方法注入(xml、注解)
1)数组
2)List集合(基本类型 String 对象)
3)对象
4)Map集合
5)Set集合
6)名称空间 <bean .... p:name="值" p:age="值"> (了解)
7) spEL 表达式 value="#{表达式}" (了解)
2、构造方法注入 (xml、注解)
1)构造方法参数名
2)构造方法参数下标 (不推荐)
七、IOC实战:使用MyBatis时,需要创建对象都交给spring ioc容器创建
spring集成MyBatis官方文档: http://mybatis.org/spring/zh/factorybean.html
1)sqlSessionFactory
2)sqlSession
3)UserMapper
第1步:导入mybatis包 + mysql驱动包+ mybatis-spring集成的包 + spring对jdbc/orm支持的包
+其他包(log4j)
[注意] mybatis-spring的版本必须与Mybatis的版本要匹配,否则报错
MyBatis-Spring MyBatis Spring Framework Spring Batch Java
2.0 3.5+ 5.0+ 4.0+ Java 8+
1.3 3.4+ 3.2.2+ 2.1+ Java 6+
第2步:beans-datasource.xml(mybatis-config.xml XXXMapper.xml)
1) 加载数据的配置信息
2)数据源(连接池)bean
3) SqlSessionFactoryBean
1)数据源 【必须】
2)mapper映射文件的位置 【必须】
3)别名 【选配】
4) 事务 DataSourceTransactionManager 【必配】
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) //
package org.springframework.jdbc.datasource;
import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.support.AbstractPlatformTransactionManager; import org.springframework.transaction.support.DefaultTransactionStatus; import org.springframework.transaction.support.ResourceTransactionManager; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionSynchronizationUtils; import org.springframework.util.Assert;
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean { @Nullable private DataSource dataSource; private boolean enforceReadOnly;
public DataSourceTransactionManager() { this.enforceReadOnly = false; this.setNestedTransactionAllowed(true); }
public DataSourceTransactionManager(DataSource dataSource) { this(); this.setDataSource(dataSource); this.afterPropertiesSet(); }
public void setDataSource(@Nullable DataSource dataSource) { if (dataSource instanceof TransactionAwareDataSourceProxy) { this.dataSource = ((TransactionAwareDataSourceProxy)dataSource).getTargetDataSource(); } else { this.dataSource = dataSource; }
}
@Nullable public DataSource getDataSource() { return this.dataSource; }
protected DataSource obtainDataSource() { DataSource dataSource = this.getDataSource(); Assert.state(dataSource != null, "No DataSource set"); return dataSource; }
public void setEnforceReadOnly(boolean enforceReadOnly) { this.enforceReadOnly = enforceReadOnly; }
public boolean isEnforceReadOnly() { return this.enforceReadOnly; }
public void afterPropertiesSet() { if (this.getDataSource() == null) { throw new IllegalArgumentException("Property 'dataSource' is required"); } }
public Object getResourceFactory() { return this.obtainDataSource(); }
protected Object doGetTransaction() { DataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject(); txObject.setSavepointAllowed(this.isNestedTransactionAllowed()); ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.obtainDataSource()); txObject.setConnectionHolder(conHolder, false); return txObject; }
protected boolean isExistingTransaction(Object transaction) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction; return txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive(); }
protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction; Connection con = null;
try { if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.obtainDataSource().getConnection(); if (this.logger.isDebugEnabled()) { this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); }
txObject.setConnectionHolder(new ConnectionHolder(newCon), true); }
txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (this.logger.isDebugEnabled()) { this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); }
con.setAutoCommit(false); }
this.prepareTransactionalConnection(con, definition); txObject.getConnectionHolder().setTransactionActive(true); int timeout = this.determineTimeout(definition); if (timeout != -1) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); }
if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(this.obtainDataSource(), txObject.getConnectionHolder()); }
} catch (Throwable var7) { if (txObject.isNewConnectionHolder()) { DataSourceUtils.releaseConnection(con, this.obtainDataSource()); txObject.setConnectionHolder((ConnectionHolder)null, false); }
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7); } }
protected Object doSuspend(Object transaction) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction; txObject.setConnectionHolder((ConnectionHolder)null); return TransactionSynchronizationManager.unbindResource(this.obtainDataSource()); }
protected void doResume(@Nullable Object transaction, Object suspendedResources) { TransactionSynchronizationManager.bindResource(this.obtainDataSource(), suspendedResources); }
protected void doCommit(DefaultTransactionStatus status) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); if (status.isDebug()) { this.logger.debug("Committing JDBC transaction on Connection [" + con + "]"); }
try { con.commit(); } catch (SQLException var5) { throw new TransactionSystemException("Could not commit JDBC transaction", var5); } }
protected void doRollback(DefaultTransactionStatus status) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); if (status.isDebug()) { this.logger.debug("Rolling back JDBC transaction on Connection [" + con + "]"); }
try { con.rollback(); } catch (SQLException var5) { throw new TransactionSystemException("Could not roll back JDBC transaction", var5); } }
protected void doSetRollbackOnly(DefaultTransactionStatus status) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction(); if (status.isDebug()) { this.logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() + "] rollback-only"); }
txObject.setRollbackOnly(); }
protected void doCleanupAfterCompletion(Object transaction) { DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction; if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.unbindResource(this.obtainDataSource()); }
Connection con = txObject.getConnectionHolder().getConnection();
try { if (txObject.isMustRestoreAutoCommit()) { con.setAutoCommit(true); }
DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel()); } catch (Throwable var5) { this.logger.debug("Could not reset JDBC Connection after transaction", var5); }
if (txObject.isNewConnectionHolder()) { if (this.logger.isDebugEnabled()) { this.logger.debug("Releasing JDBC Connection [" + con + "] after transaction"); }
DataSourceUtils.releaseConnection(con, this.dataSource); }
txObject.getConnectionHolder().clear(); }
protected void prepareTransactionalConnection(Connection con, TransactionDefinition definition) throws SQLException { if (this.isEnforceReadOnly() && definition.isReadOnly()) { Statement stmt = con.createStatement();
try { stmt.executeUpdate("SET TRANSACTION READ ONLY"); } finally { stmt.close(); } }
}
private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport { private boolean newConnectionHolder; private boolean mustRestoreAutoCommit;
private DataSourceTransactionObject() { }
public void setConnectionHolder(@Nullable ConnectionHolder connectionHolder, boolean newConnectionHolder) { super.setConnectionHolder(connectionHolder); this.newConnectionHolder = newConnectionHolder; }
public boolean isNewConnectionHolder() { return this.newConnectionHolder; }
public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) { this.mustRestoreAutoCommit = mustRestoreAutoCommit; }
public boolean isMustRestoreAutoCommit() { return this.mustRestoreAutoCommit; }
public void setRollbackOnly() { this.getConnectionHolder().setRollbackOnly(); }
public boolean isRollbackOnly() { return this.getConnectionHolder().isRollbackOnly(); }
public void flush() { if (TransactionSynchronizationManager.isSynchronizationActive()) { TransactionSynchronizationUtils.triggerFlush(); }
} } }
|
|
|
|
第3步:编写单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-datasource.xml")
public class TestMyBatis {
@Autowired
UserMapper userMapper;
@Test
public void testUser() {
List<User> users = userMapper.selectByExample(null);
System.out.println("users==>"+users);
}
}
【注意】1、spring-database.xml中的${username}默认获取的是win操作系统的用户名
故:datasource.properties文件 username=xxx 改为userName=xxxx
2、spring集成mybait的包的版本问题
mybatis-spring-1.2.2只能集成mybatis 3.2 版本 不能继承最新的 3.5.5
需要maven仓库获取mybatis-spring-2.x的版本的jar