什么是Spring ?
解决业务层与其他层的松耦合问题。
Spring的IOC的底层原理:
使用工厂+反射+配置文件的方式,实现解耦和。
Spring的快速入门案例:
1 导包
2 applicationContext的配置文件
3 实现:工厂(ApplicationContext)+反射+配置文件
IOC和DI(Spring创建对象的过程中,将对象的依赖属性注入)的概念:
依赖注入的propriety属性可以将属性中的类注入值:
Spring的工厂类(ApplicationContext):
Spring的Bean管理(XML方式):
1 无参构造
2 静态实例话工厂
3 实例工厂:
Bean的配置:
id和name:
class:
测试:
默认为单例模式:
因为是单例模式,所以打印出的地址是一样的。
多例:
persion1和persion2的指向的地址是不一样的。
Spring容器中的生命周期:
bean载入到容器的时候调用init,bean从容器中删除的时候调用destory(必须为单模式)
Spring的属性注入:
1 构造方法属性注入:
setter方式的注入:
关于对象的注入:
p名称注入:
SpEL方式注入:
注解方式:
需要引入spring-core,spring-context,spring-beans,spring-express,spring-aop
Spring的属性注入:
SpringAOP:
Spring-aop底层实现之JDK的动态的代理:
Cglib动态代理:
总结:
Spring AOP的增强类型:
前置通知,后置通知,环绕通知,抛出异常通知
Spring AOP的切面类型:
AOP的案例:
使用一般切面(advice):
引入spring的四个核心包,还有aopalliance和spring-aop的包,测试的话引入spring-test
接口:
实现类:
applicationContext.xml里面配置信息:
以前置通知为例:
带有切入点的切面是如何配置的(PointcutAdvisor):(使用cglib的格式)
创建一个dao:
spring的配置文件:
通知类(使用环绕通知):
测试类:
Spring 传统的AOP自动代理:
根据bean名称创建代理:
基于DefultAdvistorAutoProxyCreator
基于Aspectj(独立的AOP框架)注解的AOP开发:
jar包:
注解开发:
@Aspect的不同通知类型
通知中通过value属性定义切点(execution(<>?<><>(<>)<>)):
具体实现:
dao层
xml:
切面:
执行:
几个通知的注意点:
前置通知:
形参里加入JoinPoint joinPoint,可以返回[execution(* com.imooc.....................)]里面的对象
后置通知:
方法里定义一个返回值:
环绕通知:
异常通知:
After:
切点命名:
基于AspectJ的XML方式的AOP开发
建立接口和实现类:
XML的配置方式:
测试:
JDBC template
导包:
mysql-connector-java
Spring的4个包
jdbc、tx组件
spring.xml的配置
测试:
JDBC Template基本使用:
例子:
import com.imooc.sc.entity.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class Test {
private JdbcTemplate jdbcTemplate;
{
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
jdbcTemplate = (JdbcTemplate)context.getBean("jdbcTemplate");
}
public void testExecute(){
jdbcTemplate.execute("create table user1(id int,name varchar(20))");
}
public void testUpdate(){
String sql = "insert into student(name,sex) values(?,?)";
jdbcTemplate.update(sql,new Object[]{"张飞","男"});
}
public void testUpdate2(){
String sql = "update student set sex=? where id=?";
jdbcTemplate.update(sql,"女",1003);
}
public void testBatchUpdate(){
String[] sqls={
"insert into student(name,sex) values('关羽','女')",
"insert into student(name,sex) values('刘备','男')",
"update student set sex='女' where id=2001"
};
jdbcTemplate.batchUpdate(sqls);
}
public void testBatchUpdate2(){
String sql = "insert into selection(student,course) values(?,?)";
List<Object[]> list = new ArrayList<Object[]>();
list.add(new Object[]{1005,1001});
list.add(new Object[]{1005,1003});
jdbcTemplate.batchUpdate(sql,list);
}
查询简单数据:
public void testQuerySimple1(){
String sql = "select count(*) from student";
int count = jdbcTemplate.queryForObject(sql,Integer.class);
System.out.println(count);
}
public void testQuerySimple2(){
String sql = "select name from student where sex=?";
List<String> names = jdbcTemplate.queryForList(sql,String.class,"女");
System.out.println(names);
}
public void testQueryMap1(){
String sql = "select * from student where id = ?";
Map<String,Object> stu = jdbcTemplate.queryForMap(sql,1003);
System.out.println(stu);
}
public void testQueryMap2(){
String sql = "select * from student";
List<Map<String,Object>> stus = jdbcTemplate.queryForList(sql);
System.out.println(stus);
}
public void testQueryEntity1(){
String sql = "select * from student where id = ?";
Student stu = jdbcTemplate.queryForObject(sql, new StudentRowMapper(), 1004);
System.out.println(stu);
}
@org.junit.Test
public void testQueryEntity2(){
String sql = "select * from student";
List<Student> stus = jdbcTemplate.query(sql,new StudentRowMapper());
System.out.println(stus);
}
private class StudentRowMapper implements RowMapper<Student>{
public Student mapRow(ResultSet resultSet, int i) throws SQLException {
Student stu = new Student();
stu.setId(resultSet.getInt("id"));
stu.setName(resultSet.getString("name"));
stu.setSex(resultSet.getString("sex"));
stu.setBorn(resultSet.getDate("born"));
return stu;
}
}
}
事务:
编程式事务:
声明式事务:
配置database.properties
#DBCP数据库连接池配置属性详细内容可参考官网描述:
#http://commons.apache.org/proper/commons-dbcp/configuration.html
#dsName = defaultDataSource
#连接设置
username=root
password=root
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
#connectionProperties,跟进需要,可参看官方说明进行详细配置:
#<!-- 初始化连接 -->
initialSize=10
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#最大连接数量
maxActive=50
#是否在自动回收超时连接的时候打印连接的超时错误
logAbandoned=true
#是否自动回收超时连接
removeAbandoned=true
#超时时间(以秒数为单位)
#设置超时时间有一个要注意的地方,超时时间=现在的时间-程序中创建Connection的时间,如果maxActive比较大,比如超过100,那么removeAbandonedTimeout可以设置长一点比如180,也就是三分钟无响应的连接进行回收,当然应用的不同设置长度也不同。
removeAbandonedTimeout=180
#<!-- 超时等待时间以毫秒为单位 -->
#maxWait代表当Connection用尽了,多久之后进行回收丢失连接
maxWait=1000
XML文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 引入数据库连接属性配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:database.properties" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>
<!-- 配置数据源 -->
<!-- #DBCP数据库连接池配置属性详细内容可参考官网描述:
#http://commons.apache.org/proper/commons-dbcp/configuration.html
-->
<!--<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="com.mysql.jdbc.Driver" />
<property name="username" value="root" />
<property name="password" value="mysql" />
<!– 初始化连接大小 –>
<property name="initialSize" value="5"></property>
<!– 连接池最大空闲 –>
<property name="maxIdle" value="3"></property>
<!– 连接池最小空闲 –>
<property name="minIdle" value="2"></property>
</bean>-->
<!-- jdbc事务管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--事务模板 -->
<!-- 2、注释模式事务:启动使用注解实现声明式事务管理的支持 -->
<tx:annotation-driven transaction-manager="txManager" />
<!-- 想创建的服务对象:this is the service object that we want to make transactional -->
<bean id="fooService" class="com.mooc.service.DefaultFooService"/>
<bean id="xbeanService" class="com.mooc.service.XbeanServiceImpl"/>
<!-- 1、通过事务通知的模式实现事务
事务通知:the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- 以get开头的所有方法都为只读事务:all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true"/>
<!-- 其它方法使用默认事务设置:other methods use the default transaction settings (see below) -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 确保上述事务通知对定义在FooService接口中的方法都起作用(
ensure that the above transactional advice runs for any execution
of an operation defined by the FooService interface) -->
<aop:config>
<aop:pointcut id="fooServiceOperation" expression="execution(* com.mooc.service.FooService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
</aop:config>
</beans>