目录
1)底层。
2)操作 bean 管理。
1)实现对象创建
2)注解注入属性
2)准备工作
1)实现事务
3)设置隔离级别
5)其他参数
7)完全注解方式
3)函数式风格 GenericApplicationContext
一、概述
1) spring 是轻量级的J2EE的容器。
2) 解决企业级开发的复杂性。
3)两个核心服务 IOC 和 Aop。
1-IOC :控制反转 ,把创建对象的过程交给Spring处理。
2- Aop:面向切面,不修改源代码,增强项目功能。
二、Spring 之 IOC
底层
1)机制 :xml文件 工厂模式 反射
2)工厂接口
1-BeanFactor 内部接口 获取不创建对象,使用时创建对象
2. ApplicationContext 接口 常用结构 获取时即创建对象。两个实现类 fileSystemXMLApplicationContext ClassPathXmlApplicationContext
操作 bean 管理
1 什么是Bean管理
spring 创建对象
spring 注入属性
bean管理 两种实现方式 xml文件配置,注解方式。
1 基于xml 文件配置实现 Bean 管理
无参构造:
spring 底层会调用类的无参构造器来创建对象
DI: 属性注入 - set注入
有参构造注入:
p 名称空间注入:
xml 文件配置 其他特殊属性值注入
属性设置空值 -NULL
属性中有特殊符号 -CDATA
注入属性,外部Bean,例如:service 调用 dao 方法。通过xml配置完成类之间的调用
1 创建userService
package com.study.service;
import com.study.dao.UserDao;
public class UserService {
private UserDao userDao; // 设成内部属性
public void setUserDao(UserDao userDao) { //通过set方法实现注入
this.userDao = userDao;
}
public void addUser() {
System.out.println("UserService方法使用");
userDao.add();
}
}
2. 创建userDao
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("数据添加成功");
}
}
3. 配置 xml 文件
注入属性- 内部Bean
级联注入属性
注入集合类型属性
1. 创建类
public class student {
private String[] cour;
private List<String> chenji;
private Map<String,String> Class;
private Set<String> set;
public void setCour(String[] cour) {
this.cour = cour;
}
public void setChenji(List<String> chenji) {
this.chenji = chenji;
}
public void setClass(Map<String, String> aClass) {
Class = aClass;
}
public void setSet(Set<String> set) {
this.set = set;
}
}
2. 配置 xml 文件
<bean id="student" class="com.study.student">
<property name="cour">
<array>
<value>java课程设计</value>
<value>大数据开发</value>
<value>大数据提取</value>
</array>
</property>
<property name="chenji">
<list>
<value>98</value>
<value>12</value>
<value>10</value>
</list>
</property>
<property name="class">
<map>
<entry key="天才" value="课程"></entry>
<entry key="加油" value="冲刺"></entry>
</map>
</property>
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
</bean>
注入集合对象
使用 util 命名空间抽取 集合 公共使用
管理工厂Bean
factorBean 定义时的类型返回的类型不同 ,实现 FactorBean
Bean 的作用域
在Spring 中,Bean中分为单实例和多实例,默认的是单实例,即所用的该对象都是同一个。
设置多实例对象,使用bean标签中的scop属性,scop可以取两个值
1)singleton (默认)读取xml加载文件时,就已创建对象)
2)prototype 多实例,每次使用getBean ,都是不同的对象,getBean时创建对象。
3)request ,请求,每次创建对象保存请求体中。
4)session,会话,每次创建对象保存session会话中。
Bean 的生命周期
1)通过构造器创建对象实例(默认无参构造器).
2)对bean实例设置属性值 和 其他 bean 的引用 (通过set方法).
3)把 bean 实例传给bean后置处理器方法 postProessBeforeinitializtion().
4)调用 bean 的初始化方法 init-method 设置。
5)把 bean 实例传给 bean 后置处理器postProessAfterinitializtion().。
6)获取 bean 实例,该对象即可使用。
7)当容器销毁时,调用销毁方法 destory-method(实现类的close方法)。
基于xml方式,实现bean管理的自动装配
1 通过属性名称自动装配
2 通过属性类型自动装配,相同的bean只能有一个
引入外部属性文件 - Druid 连接池
1. 基础方法
2. 引入外部属性文件
1. 声明 context 名称空间
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd>
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
2. 创建properties 文件
# 使用pro.防止命名冲突
pro.driver=com.mysql.jdbc.Driver
pro.url=jdbc:mysql://localhost:3306/db_04
pro.username=root
pro.password=liubo321
3. 使用 context 标签引入properties 文件和配置
<!--引入 properties 文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--Druid 连接池 配置相关属性-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driver" value="${pro.driver}"></property>
<property name="url" value="${pro.url}"></property>
<property name="username" value="${pro.username}"></property>
<property name="password" value="${pro.password}"></property>
</bean>
基于注解方式 实现bean管理
1. 注解格式 @注解名(属性值=属性名, 属性值=属性名)
2. 简化 xml 配置。
3. 实现对象创建的四个注解
1)Component(组件)
2)Service(服务)
3)Controller(控制层)
4)Repository(仓库)
实现对象创建
1. 声明 context 名称空间 加入 aop 依赖。
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd>
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
2. context 标签加入扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.study"></context:component-scan>
</beans>
3. 对应的类添加注解
//不写value 默认是类名的首字母小写
@Component // value 值 对应 bean 中 id属性
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("数据添加成功");
}
}
控制扫描范围
include 扫描包括
exinclude 不包括
注解注入属性
1. 注入属性常用注解
1)@Autowired (根据类型注入)
2)@Qualifier (根据名称注入 要和 1 一起使用)
3)@Resource (javax包下,可以根据类型/名称注入)
4)@Value (注入普通类型属性)
@Autowired 的使用
使用创建对象注解 ,创建相关对象
@Qualifier (根据名称注入 要和 1 一起使用)
@Resource (可以根据类型/名称注入)
按 类型 装配
按 名称装配
完全注解 不需要配置文件
1. 创建配置类 - 代替xml文件
2. 测试类
三、Spring 之 AOP
概念
1 面向切面编程,通过预编译和运行过程动态代理实现。
2 是OOP的延续,减低耦合性。
3 不改动源代码 即可 增加逻辑。
术语
1)连接点
可以为其增加逻辑的方法。
2)切入点
真正将该方法增强的具体的方法。
3)通知(增强)
增强代码的具体逻辑。
3)切面
是一个过程,将通知应用到切入点中的过程。
实现过程
1)spring 基于AspectJ框架实现AOP。
2)基于注解,基于xml文件配置
3)切入点表达式
execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表]))
表达式 | execution( * com.study.spring.ArithmeticCalculator.*(…)) |
含义 | ArithmeticCalculator接口中声明的所有方法。第一个※代表任意修饰符及任意返回值。第二个“*”代表任意方法。“…”匹配任意数量、任意类型的参数。若目标类、接口与该切面类在同一个包中可以省略包名。 |
可以使用逻辑运算符
//任意类中第一个参数为int类型的add方法或sub方法
execution (* *.add(int,..)) || execution(* *.sub(int,..))
//匹配不是任意类中第一个参数为int类型的add方法
!execution (* *.add(int,..))
注解方式实现
1. 创建类,类中有方法
public class User {
// User add 被增强的方法
public void add() {
System.out.println("user.add");
}
}
2. 创建增强类,编写增强代码逻辑
public class UserProxy {
// 使得该方法 在 User add 方法之前调用 即 前置通知
public void before() {
System.out.println("Before"); // 通知
}
}
3. 通知配置
1)在spring开启注解扫描。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.study"></context:component-scan>
</beans>
2)使用注解创建User和UserProxy对象。
3)在增强类添加@AspectJ注解。
4)在spring配置文件中开启生成代理对象。
<!--开启 aspectJ 生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
5)配置不同类型的通知,即在增强类中的方法上添加通知类型的注解。
@Component
@Aspect // 表示切面类
public class UserProxy {
// 使得该方法 在 User add 方法之前调用 即 前置通知
@Before(value = "execution(* com.AspectJ.User.add(..))")
public void before() {
System.out.println("Before"); // 通知
}
}
各种不同类型的通知
/**
* 增强类
*/
@Component
@Aspect // 表示切面类
public class UserProxy {
// 使得该方法 在 User add 方法之前调用 即 前置通知
@Before(value = "execution(* com.AspectJ.User.add(..))")
public void before() {
System.out.println("Before"); // 通知
}
// 方法之后执行,最终通知
@After(value = "execution(* com.AspectJ.User.add(..))")
public void after() {
System.out.println("after");
}
// 方法返回结果之后执行,出现异常不执行,返回通知
@AfterReturning(value = "execution(* com.AspectJ.User.add(..))")
public void afterReturning() {
System.out.println("AfterReturning");
}
// 方法出现异常执行,异常通知
@AfterThrowing(value = "execution(* com.AspectJ.User.add(..))")
public void afterThrowing() {
System.out.println("AfterThrowing");
}
// 环绕通知
@Around(value = "execution(* com.AspectJ.User.add(..))")
public void around (ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前.....");
proceedingJoinPoint.proceed(); // 调用原来的方法
System.out.println("环绕之后.....");
}
}
相同的切入点抽取
优先级设置 @Order(数字整形) 越小优先级越高,多个增强类对同一个方法增强。
基于xml配置
<!--创建两个对象 增强类和被增强类-->
<bean id="user" class="com.AspectJ.User"></bean>
<bean id="userProxy" class="com.AspectJ.UserProxy"></bean>
<!--配置切入点-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="p" expression="execution(* com.AspectJ.User.add(..))"/>
<!--配置切面-->
<aop:aspect ref="userProxy">
<!--配置具体方法-->
<aop:before method="before" pointcut-ref="p" />
</aop:aspect>
</aop:config>
Spring 之 jdbcTemplate
概念
1)Spring 对jdbc进行了封装,简单实现对数据库的操作。
准备工作
1. 引入druid mysql连接的jar包。
2. spring 配置文件完成对数据连接池 和 jdbcTemplate 及 开始组件扫描
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd>
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql://localhost/3306/db_04"></property>
<property name="username" value="root"></property>
<property name="password" value="liubo321"></property>
<property name="driver" value="com.mysql.jdbc.Driver"></property>
</bean>
<!--配置jdbcTemplate,注入dataSource对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启组件扫描-->
<context:component-scan base-package="com"></context:component-scan>
</beans>
3. 创建UserService,UserDao,UserDaoimpl,对象
jdbcTemplate.update 实现增删改功能
查询功能
1. 单条记录
2. query方法查询返回对象集合
3. 批量添加 / 删除 / 修改 差不多一致,注意 Object[ ] 的参数顺序,要与sql语句的?对应。
Spring之事务操作
1)事务是数据库操作的最基本的单元,逻辑上一组操作,要么全部成功,要么失败。
2)四个特性(ACID):
1 原子性
要么全部成功,要么失败。
2 一致性
操作之前 和 操作之后的总量是不变的。
3 隔离性
多事务操作,之间不产生影响。
4 持久性
提交事务时,数据真正的发生变化。
实现事务
1)编程式事务管理。
2)声明式事务管理。(常用)
1-基于xml配置。
2-注解方式。
xml配置 + 注解方式
1. 配置事务管理器
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.jdbcTemplate"></context:component-scan>
<!--配置数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql://localhost:3306/db_04"></property>
<property name="username" value="root"></property>
<property name="password" value="liubo321"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
<!--配置jdbcTemplate,注入dataSource对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开始事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
2. 写入 tx 名称空间 开启事务注解
<!--开始事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
3. 添加注解 类/ 方法上。
@Transactional
1. 类上表示改下所有的方法都为事务。
2. 方法上,仅代表该方法。
注解传播行为
事务隔离级别
多事务操作之间不会操作影响 - 隔离性。
2)不考虑会有很多问题:
1)脏读。
一个未提交的事务读取到另一个未提交的数据。
2)不可重复读。
一个未提交的事物读取到另一个已经提交的事务。
3)幻读。
读取到另一个事务未提交的添加数据。
设置隔离级别
设置事务的传播行为和隔离级别
@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
public class UserService {
其他参数
1. timeout (超时)
1)事务在一定时间内进行提交,如果超出时间未提交,会做事务的回滚。
2)默认值 -1 (关闭超时) 单位为秒。
2. readOnly (是否只读)
1)默认值是 false
2)设置为true,只能做查询操作。
3. rollbackFor (回滚)
1)设置出现异常,进行回滚。
4. norollbackFor
1)设置出现那些异常,不进行回滚。
事务操作(基于xml配置)
1. 配置事务管理器
2. 配置通知
3.配置切入点。
!--开始事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置通知-->
<tx:advice id="advice1">
<tx:attributes>
<!--指定那些方法名符合规则的方法添加事务-->
<tx:method name="countMoney"/> <!--方法名为countMoney添加事务-->
<!--<tx:method name="count*"/>-->
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pointCut1" expression="execution(* com.study.service.UserService.*(..))"/>
<!--配置切面-->
<aop:advisor advice-ref="advice1" pointcut-ref="pointCut1"></aop:advisor>
</aop:config>
完全注解方式
@Configuration // 表示注解类
@ComponentScan(basePackages = "com.study") // 组件扫描
@EnableTransactionManagement // 开启事务
public class TransactionConfig {
// 创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/db_04");
dataSource.setUsername("root");
dataSource.setPassword("liubo321");
return dataSource;
}
//创建 JdbcTemplate
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
// 注入dataSource 到 IOC容器中 根据类型注入dataSource
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
// 创建事务管理器
@Bean
public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
Spring 新功能
1) 日志封装
Log4j2
2)Nullable的注解
3)函数式风格 GenericApplicationContext
创建对象,并且将该对象交给spring容器管理
指定名称
4)支持整合 JUnit5 框架
/**
* 整合 Junit5
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:test.xml")
public class Junit5 {
@Autowired
private UserService userService;
@Test
public void test() {
userService.addUser();
}
}
代替
@Test
public void test1() {
ApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.addUser();
}
Webflux - 后期补充
1)响应式编程
2)执行流程和API
3)基于注解编程模型实现
4)基于函数式编程实现