web.xml配置
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
概述
- Spring是轻量级的开源的JavaEE框架
- Spring可以解决企业应用开发的复杂性
- Spring有两个核心部分:IOC和AOP
- IOC:控制反转,把创建对象过程交给Spring进行管理
- AOP:面向切面,不修改源代码进行功能增强
Spring特点
概念:控制反转,把对象创建和对象之间的调用过程交给Spring来管理
- 使用IOC的目的:降低耦合度
-
IOC两个接口
Spring提供IOC实现的两种方式(两个接口:BeanFactory和ApplicationContext)
BeanFactory(加载配置文件时不会创建对象,在使用时才会创建对象)
- ApplicationContext(加载配置文件时就会创建对象)
- FileSystemXmlApplicationContext(实现类,在参数上要填配置文件的绝对路径)
- ClassPathXmlApplicationContext(实现类,在参数上要填配置文件的相对路径,以src为基准) ```java //使用第一种方式,第一个接口 BeanFactory context = new ClassPathXmlApplicationContext(“bean.xml”);
//使用第二种方式,第二个接口 ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”); ApplicationContext context = new FileSystemXmlApplication(“绝对路径”);
<a name="JDO9k"></a>### Bean管理(xml配置文件方式)Bean管理主要有创建对象和注入属性两件事<br />Bean管理的实现方式有xml和注解两种方式<a name="JadJO"></a>#### 基于xml的方式1. 创建对象
<?xml version=”1.0” encoding=”UTF-8”?>
由spring管理bean(三种方法)
//1.
//2.静态工厂
<bean id="userServiceImpl2" class="com.zy.service.impl.Factory2" factory-method="instance"></bean>
//3.如果要不是静态方法
<!-- 实例化工厂id唯一标识 一般是类名首字母小写factory-bean 工厂的bean对象factory-method指定对应的工厂方法 方法名--><bean id="userServiceImpl3" factory-bean="factory3" factory-method="instance"></bean>
//
//4.创建一个工厂类继承FactoryBean,实现其中方法,随后将
2. 注入属性
1.set注入(必须有set方法)
<!-- name : userService中需要赋值的属性value 可以赋普通值--><property name="userDao" value="userDaoImpl"></property></bean>
2.p名称空间注入 在开头要加上 xmlns:p=”http://www.springframework.org/schema/p“
//示例<bean id="book" class="com.atguigu.spring.Book" p:bname="" p:bauthor=""></bean>
3.设置空值及特殊符号
//空值
//特殊符号 <![CDATA[《南京》]]><property name="address"><value><![CDATA[《南京》]]></value></property>
4.外部bean和内部bean及级联赋值
//外部bean
//内部bean<bean id="userService" class="..." ><property name="userDao"><bean id="userDaoImpl" class="..."><property></property></bean></property></bean>//用外部bean级联赋值 要有get方法<property name="dept" ref="dept"></property><property name="dept.dname" value="技术部"></property>
5.构造器注入(要有对应的构造方法)
//用名称的方式填参数<constructor-arg name="XX" value="xx"/></bean>
6.注入基本类型,数组,List,Set,Map
7.在array,list,set,map设置值为对象的情况 使用标签
```8.将集合注入部分提取出来在<beans>头部添加xmlns:p="http://www.springframework.org/schema/util"xsi:schemaLocation上添加"http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsd"<util:list id="bookList"><value>理想国</value><value>国富论</value></util:list><bean id="book" class="com.atguigu.spring5.collectiontype.Book"><property name="list" ref="bookList"></property></bean>
bean管理(作用域)
singleton和prototype的区别 1. singleton是单实例,prototype是多实例 1. 若为singleton则在加载配置文件的时候就会创建bean,若为prototype则在使用getBean时创建bean
<bean id="" class="" scope=""></bean>
#### bean管理(生命周期)
1. 执行构造方法创建bean实例
1. 调用set方法设置属性值
1. 执行初始化的方法(需要配置)
1. 获取创建的bean实例对象
1. 关闭容器时执行销毁方法(需要配置)
bean的两个参数init-method和destroy-method<bean id="" class="" init-method="" destroy-method="" scope=""></bean>
完整生命周期是7步,添加后置处理器,前置在第三步之前执行,后置在第三步之后执行添加后置处理器的步骤: 1. 创建一个后置处理器类,实现BeanPostProcessor接口 1. 重写BeanPostProcessor中的前置处理方法和后置处理方法 1. 在xml配置文件中创建这个后置处理器类 #### xml方式的自动装配 使用bean的autowired参数,取值有:byName和byType
<bean id="" class="" init-method="" destroy-method="" scope="" autowired=""></bean>
#### 引入外部属性文件
1. 添加命名空间
xmlns:context="http:www.springframework.org/schema/context"
xsi:schemaLocation="xmlns:context=http:www.springframework.org/schema/context/spring-context.xsd"
2. 引入属性文件
<context:property-placeholder location="classpath:jdbc.properties"/>
3. 使用标识符${}
### Bean管理(注解方式)
@Component@Controller
@Service
@Repository —- #### 创建对象 1. 引入spring-aop依赖 1. 添加命名空间 xmlns:context=”http:www.springframework.org/schema/context”
xsi:schemaLocation=”xmlns:context=http:www.springframework.org/schema/context/spring-context.xsd” 3. 开启组件扫描 扫描多个包则使用逗号(,)隔开
<context:component-scan base-package="com.atguigu"></context:component-scan>
3. 在类上面添加创建注解
组件扫描的细节化配置(过滤):
1.设置哪些内容不扫描
<context:component-scan base-package="com.atguigu">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
2.设置扫描哪些内容
<context:component-scan base-package="com.atguigu">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
#### 属性注入
@Autowired:根据属性类型进行自动装配(默认按类型,类型匹配不到则属性的bean名字匹配)@Autowired(required=false)表示这个属性不是必须的,若装配出错不会报错,但使用该属性调用方法会报空指针错误
@Quealifier(value=”名称”):根据属性名称进行注入
@Resource(name=”名称”):可以根据类型注入,可以根据名称注入(默认按名字,其次按类型)
@Value(value=”值”):注入普通类型注入
不需要set方法 #### 完全注解开发 1. 创建配置类,代替xml配置文件 使用@Configuration和@ComponentScan(basePackages={“com.atguigu”})注解
@Configuration
@ComponentScan(basePackages={"com.atguigu"})
public class SpringConfig {
}
2. 测试类
加载配置类时要将ClassPathXmlApplicationContext替换为AnnotationConfigApplicationContext
java
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
## AOP(面向切面编程)
### 底层原理
使用动态代理的方式
1. 有接口的情况下,通过创建接口实现类代理对象,增强类的方法
1. 没有接口的情况,通过创建子类的代理对象,增强类的实现方法
#### JDKProxy动态代理实现
### AOP术语
1. 连接点
1. 切入点
1. 通知(增强)
1. 前置通知
1. 后置通知
1. 环绕通知
1. 异常通知
1. 最终通知
4. 切面
### AOP的准备工作
AOP的设置分为xml配置方式和注解方式两种
#### 1. 引入AOP相关的依赖
- com.springsource.net.sf.cglib.jar
- com.springsource.org.aspectj.weaver.jar
- com.springsource.org.aopalliance.jar
- spring-aspect.jar
#### 2. 切入点表达式(还有很多没学)
1. 切入点表达式的作用:知道对哪个类里面的哪个方法进行增强
1. 语法结构:execution([权限修饰符][返回类型][类全路径]方法名称)
示例1:对com.atguigu.dao.BookDao类里面的add方法进行增强
execution(* com.atguigu.dao.BookDao.add(..))
示例2:对com.atguigu.dao.BookDao类里面的所有方法进行增强
execution(* com.atguigu.dao.BookDao.*(..))
### AOP注解开发
#### AOP基本配置流程
1. 创建被增强类
1. 创建增强类
1. 进行通知的配置(在spring配置文件上配置)
配置文件的命名空间要加上context和aop开启组件扫描
命名空间
xmlns:context="http:www.springframework.org/schema/context"
xmlns:context="http:www.springframework.org/schema/aop"
xml:schemaLocation="http:www.springframework.org/schema/context http:www.springframework.org/schema/context/spring-context.xsd
http:www.springframework.org/schema/aop http:www.springframework.org/schema/aop/spring-aop.xsd"
组件扫描
<context:component-scan base-package="com.atguigu.aop"></context:component-scan>
生成代理对象的配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
4. 为被增强类和增强类加上注解
被增强类:@Component增强类:@Component、@Aspect
增强类中的方法可以加的通知注解:
@Aspect
public class Proxy{
@Before(value="execution(* com.atguigu.aop.add(..))") //前置通知
public void before(){
}
@After(value="execution(* com.atguigu.aop.add(..))") //后置通知
public void after(){
}
@Around(value="execution(* com.atguigu.aop.add(..))") //环绕通知
public void around(ProceedJoinPoint proceedJoinPoint){
System.out.println("环绕之前");
//被增强方法执行
proceedJoinPoint.proceed();
System.out.println("环绕之前");
}
@AfterReturning(value="execution(* com.atguigu.aop.add(..))") //最终通知
public void afterReturning(){
}
@AfterThrowing(value="execution(* com.atguigu.aop.add(..))") //异常通知
public void afterThrowing(){
}
}
顺序:
环绕之前
前置通知
被增强方法
环绕之后
后置通知
最终通知
#### AOP进一步配置
1. 提取出相同切入点
在增强类中写新写一个方法pointdemo
@Component
@Aspect
public class Proxy{
@PointCut(value="execution()")
public void pointdemo(){}
@Before(value="pointdemo")
public void before(){}
@After(value="pointdemo")
public void after(){}
}
2. 设置增强类的优先级
在类上使用注解@Order(数字),数字越小优先级越高
#### AOP完全注解开发
使用配置类,和之前的bean管理类似
java
@Configuration
@ComponentScan(basePackage = {"com.atguigu"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAOP{}
### AOP使用xml配置文件开发
```
1.创建对象,被增强类与增强类
2.aop配置
//配置切面<aop:aspect ref="bookProxy"><aop:before method="before" pointcut-ref="p"/></aop:aspect>
<a name="Dtjo1"></a>## JdbcTemplate<a name="ZzWOF"></a>### 准备工作1. 引入jar包1. druid-1.1.9.jar1. mysql-connector-java-5.1.7-bin.jar1. spring-jdbc-5.2.6.RELEASE.jar1. spring-tx-5.2.6.RELEASE.jar(事物)1. spring-orm-5.2.6.RELEASE.jar(整合mybatis需要)2. 配置数据库连接池
3. 配置JdbcTemplate对象
<a name="OLKdV"></a>
### 增删改查操作
<a name="MlxSj"></a>
#### 添加操作
jdbcTemplate.update(sql, Object... args);<br />sql:SQL语句<br />args:可变参数
<a name="hIOdF"></a>
#### 修改操作
与添加操作相同
<a name="vJLyp"></a>
#### 删除操作
与添加操作相同
<a name="0YNVY"></a>
#### 查询操作
1. 查询返回一个值
jdbcTemplate.queryForObject(String sql, Class<T> requiredType);<br />sql:SQL语句<br />requiredType:返回值类型
2. 查询返回一个对象
jdbcTemplate.queryForObject(String sql, RowMapper<T> rowMapper, Object... args);<br />sql:SQL语句<br />rowMapper:RowMapper是一个接口,返回不同类型的数据则使用这个接口下不同的实现类,这里返回一个对象使用new BeanPropertyRowMapper<Book>(Book.class)<br />args:可变参数
3. 查询返回集合
jdbcTemplate.query(String sql, RowMapper rowMapper, Object... args);<br />参数解释与上同,返回一个list集合
<a name="hWEqT"></a>
#### 批量添加操作
jdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs);<br />返回int数组
<a name="9ZDfK"></a>
#### 批量修改、删除
与批量添加相同 batchDelete
<a name="cM3bG"></a>
## 事务操作
<a name="MDfkz"></a>
### 概述
1. 概念:事务是数据库操作最基本单元,逻辑上一组操作要么都成功,要么都失败
1. 四个特性:原子性、一致性、隔离性、持久性
1. Spring事务管理有编程式事务管理和声明式事务管理
1. 编程式事务管理
1. 声明式事务管理
1. 基于注解方式
1. 基于xml配置文件方式
<a name="YEaTC"></a>
### 事物管理准备配置
1. 在Spring中配置事物管理器
//创建数据源对象
//创建jdbcTemplate对象
//创建事务管理器
2. 在Spring配置文件中开启事物注解
//引入命名空间
xmlns:tx=”http://www.springframework.org/schema/tx“
xsi:schemaLocation=”http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd“
//开启事物注解
3. 在类上或方法上添加事务注解(@transactional)
在类上添加则表示为类上所有方法添加<br />在方法上添加表示只在这个方法上添加
<a name="nW19S"></a>
### 事务管理参数配置
1. propagation:事务传播行为
1. isolation:事务隔离级别
1. timeout:超时时间
1. readOnly:是否只读
1. rollbackFor:回滚
1. noRollbackFor:不回滚
<a name="bBWgX"></a>
#### propagation(传播行为)
有事务方法调没事务方法,有事务方法调有事务方法,没事务方法调有事务方法<br />参数可取值:
1. REQUIRED:如果有事务在运行,当前方法(被调用方法)就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行
1. REQUIRED_NEW:当前方法(被调用方法)必须启动新事务,并在它自己的事务内运行,如果事务正在运行,应该将它挂起
1. SUPPORTS:如果事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中
1. NOT_SUPPORTED:当前方法不应该运行在事务中,如果有运行的事务,将它挂起
1. MANDATORY:当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
1. NEVER:如果事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行
1. NESTED
<a name="ILWWJ"></a>
#### isolation(隔离级别)
@Transactional(isolation=Isolation.READABLE_READ)<br />问题:
1. 脏读:读到未提交数据
1. 不可重复读:前后两次读的数据不一致,中间被提交修改
1. 虚读(幻读)
参数取值:
1. READ UNCOMMITTED(读未提交):不可解决
1. READ COMMITTED(读已提交):可解决脏读
1. REPEATABLE READ(可重复读):可解决不可重复读
1. SERIALIZABLE(串行化)都可解决
<a name="mllCQ"></a>
#### timeout(超时时间)
事务需要在一定时间内进行提交,如果不提交则进行回滚<br />默认值是-1(表示不超时),设置时间以秒为单位
<a name="F3M1v"></a>
#### readOnly(是否只读)
默认是false,可改为true
<a name="DlLsQ"></a>
#### rollbackFor(回滚)
设置出现哪些异常进行事务回滚
<a name="D2ODF"></a>
#### noRollbackFor(不回滚)
设置出现哪些异常不进行事务回滚
<a name="vNhu8"></a>
### 事务xml配置实现方式
//1.创建事务管理器
//2.配置通知
//3.配置切入点和切面
<a name="4tDPA"></a>### 事务管理完全注解开发```java@Configuration@ComponentScan(basePackage = {"com.atguigu"})@EnableTransactionManagement //开启事务public class ConfigTX{//创建数据库连接池@Beanpublic DruidDataSource getDruidDataSource(){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName();dataSource.setUrl();dataSource.setUsername();dataSource.setPassword();return dataSource;}//创建JdbcTemplate对象@Beanpublic JdbcTemplate getJdbcTemplate(DataSource dataSource){//注入数据源dataSourceJdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}//创建事务管理器@Beanpublic DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;}}
Spring5新功能
整合通用日志
@Nullable注解
可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性值可以为空,参数可以为空
整合JUnit测试
JUnit4整合
//1.引入jar包spring-test.jar//2.为类加注解@RunWith(SpringJUnit4ClassRunner.class) //单元测试框架@ContextConfiguration("classpath:bean1.xml") //加载配置文件public class JTest4 {@AutoWiredprivate UserService userService;@Testpublic void test1() {userService.accountMoney();}}
JUnit5整合
//1.引入jar包spring-test.jar//2.为类加注解//3.JUnit5的jar包引入@ExtendWith(SpringExtension.class) //单元测试框架@ContextConfiguration("classpath:bean1.xml") //加载配置文件//以上两个注释可用@SpringJUnitConfig(locations = "classpath:bean1.xml")替代public class JTest4 {@AutoWiredprivate UserService userService;@Testpublic void test1() {userService.accountMoney();}}
