spring5学习主要内容介绍
第一章 springd的基本概念
第二章 ioc容器
第三章 aop
第四章 jdbctemplate
第五章 事务管理
第六章 spring5 新特性
第一章 spring的基本概念:
spring的定义
spring是轻量级的开源javaee框架
spring 可以解决企业级应用开发的复杂性
spring 有两个核心的内容
1 ioc 控制反转,将对象的创建交给spring进行管理
2 aop 面向切面编程,不修改源代码进行功能增强
spring 特点
1 方便解耦 简化开发
2 aop编程支持
3 方便测试 junit
4 方便和其他框架整合
5 只是对事务的支持
6 Java源码是最经典的源码 降低api开发难度
spring 入门案例
1 下载地址
Spring FrameworkSpring FrameworkSpring Framework(ga标志为稳定版本标志 一班下载该版本)
2 进入github打开
Spring Framework Artifacts · spring-projects/spring-framework Wiki · GitHub
Packages - repo.spring.io (下载界面)
spring核心功能及其对应的核心包
3 开始写示例代码
1 创建一个普通类
public class User {
int age;
String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHole() {
}
}
2 创建spring配置文件,在配置文件中配置创建的对象
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean id="user" class="com.test.bean.User"> </bean> </beans>
3 进行测试代码编写
import com.test.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {
@Test
public void test() {
// 加载spring配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
// 获取spring管理的对象
User user = applicationContext.getBean("user", User.class);
user.sayHole();
}
}
第二章 ioc容器
1 ioc定义
控制反转,把对象的创建和对象之间调用过程交给spring 进行管理
使用ioc目的:为了 耦合度降低
入门案例就是ioc的一个实现
2 ioc 底层原理
主要用到的技术 xml解析 ,工厂模式,反射(共同降低耦合度)
3 图解
原始方式 耦合度过高 不利于程序扩展。
工厂模式 主要运用于解耦合 ioc的过渡。 工厂中也有耦合 但是降低了
ioc的调过程
1 第一步 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.test.bean.User">
</bean>
</beans>
2 第二步有service 和dao类 创建工厂类 工厂类进一步操作
4 ioc接口(beanfactory)
ioc思想是基于ioc容器完成的,ioc容器底层 就是对象工厂
ioc容器实现的两种方式:(两个接口)
beanFactory ioc最基本的实现方式 开发中不常用, spring内部使用。
加载xml文件的时候不会创建对象在获取对象的时候才去创建对象(缺点)
ApplicationContext beanfactory的接口的子接口提供更多强大的功能 一般给开发人员使用。
加载 xml配置文件的时候就将bean创建
ApplicationContext 一些主要的实现类
FileSystemXmlApplicationContext (盘里面的路径 全路径) ClassPathXmlApplicationContext(src下的路径)
BeanFactory 一些主要的实现类
5 ioc的bean管理
bean管理:
1 指的是两个操作 创建对象 注入属性
2 bean管理的两种方式 基于xml 和 基于注解方式
1 ioc操作bean管理(基于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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置对象 -->
<!-- 基本属性配置-->
<!--id="user" 配置含义为为创建的对象去一个别名-->
<!--name="beanName"作用同id 一致 但不常用-->
<!-- class="com.test.bean.User" 配置创建类的类相对路径-->
<bean id="user" class="com.test.bean.User" name="beanName">
<!--配置属性-->
<!--无参注入创建对象的时候 默认执行的是无参构造按时创建的对象-->
</bean>
</beans>
2 有参数创建对象
di 注入属性 是ioc创建对象过程的中一个流程
类注入方式
1 set方式注入
@Test
public void test2() {
Book book = new Book();
book.setAuhtor("作者");
}
2 有参构造函数方式注入
@Test
public void test3() {
Book book = new Book("书名","作者");
}
di方式注入
第一种方式 使用set方式注入基本类型属性
<!--set方式注入对象属性-->
<bean id="book" class="com.test.bean.Book" name="bokk">
<!--配置属性-->
<!--无参注入创建对象的时候 默认执行的是无参构造按时创建的对象-->
<!--set方式注入对象属性-->
<!--name="name" 对象属性名字 value=属性值-->
<property name="name" value="name"></property>
<property name="auhtor" value="author"></property>
</bean>
@Test
public void test4() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Book book = applicationContext.getBean("book", Book.class);
System.out.println(book.toString());
}
p 名称空间注入
第二种方式 使用有参构造函数注入基本类型属性
<!--有参方式注入对象属性-->
<bean id="book" class="com.test.bean.Book" name="bokk">
<!--配置属性-->
<!--无参注入创建对象的时候 默认执行的是无参构造按时创建的对象-->
<!--set方式注入对象属性-->
<!--name="name" 对象属性名字 value=属性值-->
<!--<property name="name" value="name"></property>-->
<!--<property name="auhtor" value="author"></property>-->
<!--有参方式注入对象属性-->
<constructor-arg name="name" value="name"></constructor-arg>
<constructor-arg name="auhtor" value="auhtor"></constructor-arg>
</bean>
<bean id="book" class="com.test.bean.Book" name="bokk">
<!--配置属性-->
<!--无参注入创建对象的时候 默认执行的是无参构造按时创建的对象-->
<!--set方式注入对象属性-->
<!--name="name" 对象属性名字 value=属性值-->
<!--<property name="name" value="name"></property>-->
<!--<property name="auhtor" value="author"></property>-->
<!--有参方式注入对象属性-->
<!--<constructor-arg name="name" value="name"></constructor-arg>-->
<!--<constructor-arg name="auhtor" value="auhtor"></constructor-arg>-->
<constructor-arg index="0" value="name"></constructor-arg>
<constructor-arg index="1" value="auhtor"></constructor-arg>
</bean>
xml注入其他对象属性(非基本类型属性)
1 注入控制空值 特殊符号
<!--空值标签注入-->
<bean id="book" class="com.test.bean.Book">
<property name="name">
<null></null>
</property>
</bean>
<!--特殊符号-->
<bean id="book" class="com.test.bean.Book">
<property name="name" >
<value><![CDATA[<<四川>>]]></value>
</property>
</bean>
2 属性 外部 bean注入(service层调用dao service注入dao层bean)
原始方式
public class Userservice {
public void sayHole() {
UserDao userDao = new UserDao();
userDao.sayHole();
}
}
xml注入
<!--userServie对象创建-->
<bean id="userservice" class="com.test.service.Userservice">
<!--ref="userDao 外部bean注入-->
<property name="userDao" ref="userDao"></property>
</bean>
<!--userDao对象创建-->
<bean id="userDao" class="com.test.dao.UserDao">
</bean>
@Test
public void test5() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Userservice book = applicationContext.getBean("userservice", Userservice.class);
book.sayHole();
}
注意对象注入的类需要 get和set方法注入 或者 重写构造函数的方式 否则会报错
Bean property 'userDao' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter
3 内部bean和级联赋值
一对多关系 部门和员工的关系
配置xml方式
<!--创建员工对象-->
<bean id="emp" class="com.test.bean.Emp">
<!--基本属性赋值-->
<property name="ename" value="为我们"></property>
<property name="gender" value="男"></property>
<!--对象属性值赋值-->
<property name="dept">
<!-- 内部bean注入-->
<bean name="" class="com.test.bean.Dept">
<property name="name" value="sdfsd"></property>
<property name="num" value="ew"></property>
</bean>
</property>
</bean>
4 注入属性级联赋值
第二种
4 xml注入集合类型属性
创建相关对象属性
1 注入数组类型
2 注入list类型
3 注入Map类型
4 注入set集合
5 集合中设置对象类型的值
6 提取公共部分值的方式
spring中的两种bean(一种是普通bean 一种是工厂bean 内置)
7 工厂bean的创建 在配置文件中配置的bean类型和返回的类型不一样
一 常见一个类作为一个工厂bean
返回对象为其他类型对象
1 创建工厂实现类
8 bean管理中的 bean的作用域 和 bean的生命周期
1 spring里面 设置创建的bean的实列是单实例还是多实列
spring中创建的对象默认的是单示例
@Test
public void test6() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Emp emp = applicationContext.getBean("emp", Emp.class);
Emp emp2 = applicationContext.getBean("emp", Emp.class);
System.out.println(emp ==emp2); // true 单实例
}
设置多实列
<!--scope="prototype" 设置多实例-->
<bean id="emp" class="com.test.bean.Emp" scope="prototype">
<!--基本属性赋值-->
<property name="ename" value="为我们"></property>
<property name="gender" value="男"></property>
<!--对象属性值赋值-->
<property name="dept">
<!-- 内部bean注入-->
<bean name="" class="com.test.bean.Dept">
<property name="name" value="sdfsd"></property>
<property name="num" value="ew"></property>
</bean>
</property>
</bean>
scope="prototype"
2 bean的生命周期
对象的创建和对象的销毁过程
对象的创建
1 通过对象构造器创建
2 对对象的属性注入 调用set方法设置
初始化前置处理器
3 调用对象的初始化方法
初始化后置处理器
4 bean使用
5 容器关闭时 调用bean的销毁方法
9 xml配置对象的 自动装配
自动装配 根据指定的装配规则 spring自动将属性注入到对象
手动装配示例
<bean id="emp" class="com.test.bean.Emp" scope="prototype">
<!--基本属性赋值-->
<property name="ename" value="为我们"></property>
<property name="gender" value="男"></property>
<!-- 手动装配-->
<!--对象属性值赋值 手动装配-->
<property name="dept">
<!-- 内部bean注入-->
<bean name="" class="com.test.bean.Dept">
<property name="name" value="sdfsd"></property>
<property name="num" value="ew"></property>
</bean>
</property>
</bean>
自动装配示例
<!-- autowire="byType" 自动装配 -->
<bean id="emp" class="com.test.bean.Emp" scope="prototype" autowire="byType">
<!--基本属性赋值-->
<property name="ename" value="为我们"></property>
<property name="gender" value="男"></property>
</bean>
<bean name="dept" class="com.test.bean.Dept">
<property name="name" value="sdfsd"></property>
<property name="num" value="ew"></property>
</bean>
10 xml中引入外部的xml配置文件
1 直接配置德鲁伊数据库
2 引入德鲁伊jar包
<bean id="dataResourse" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///jdbc?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="qisini"/>
<property name="initialSize" value="3" />
<property name="maxActive" value="5" />
<property name="maxWait" value="3000" />
</bean>
3 引入支持外部引入配置文件
* 引入 context 名称空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
4 引入外部属性文件
<!-- 引入配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--使用表达式使用配置文件的值-->
<bean id="dataResourse" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="initialSize" value="3"/>
<property name="maxActive" value="5"/>
<property name="maxWait" value="3000"/>
</bean>
2 ioc操作bean管理(基于注解)
1 注解
注解是代码的特殊标记 格式 @注解名称(属性名字=属性值 ,属性名称= 属性值..)
注解可以作用在类上 方法上等
简化xml配置
2 bean管理 注解
@Component:除三层以外的其它层:实体层;
@Controller:控制层/action/servlet;
@Service:业务逻辑层service 的实现类;
@Repository:数据访问层/持久层 dao/mapper。
spring中的不同注解都可以创建对象 可以混合使用 但是不建议这样。 遵循字面规范
3 基于注解实现对象的创建
1 前置条件 要想使用注解的方式首先需要引入aop依赖
2 开启组件扫描
<!--开启组件扫描 生成跟类对象实列 多个包扫描使用逗号隔开-->
<context:component-scan base-package="com ,com.test"></context:component-scan>
3 创建类 并使用注解生成对象
import com.test.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller(value = "userTestService")
//value 值可以不写 为生成的对象实例去一个名字。 不写默认为小写
public class UserTestService {
@Autowired // 自动装配dao对象
private UserDao userDao;
public void sayHole() {
userDao.sayHole();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
@Test
public void test6() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserTestService userTestService = applicationContext.getBean("userTestService", UserTestService.class);
userTestService.sayHole();
}
4 开启组件扫描的细节问题
<context:component-scan base-package="com ,com.test">
<!-- 设置只扫 com ,com.test 包中的 Controller注解类 其他类型的注解忽略-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
<!-- 设置不 com ,com.test 包中的 Service注解类 其他类型的注解加载-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"></context:exclude-filter>
</context:component-scan>
5 基于注解实现对象的属性注入
@AutoWired | 根据属性 类型(对象的类型) 自动装配 |
@Qualifier | 根据属性的 名称(用户定义的实例名称或则默认名称)注入要和 @AutoWired一起使用 |
@Resource | 可以根据 类型输入也可以根据名称注入 |
@Value | 注入普通类型属性 |
@AutoWired自动装配 |
@Repository
public class UserDao {
public void sayHole() {
System.out.println("sfwefweew");
}
}
@Controller(value = "userTestService")
//value 值可以不写 为生成的对象实例去一个名字。 不写默认为小写
public class UserTestService {
@Autowired // 自动根据类型装配 不需要set方法 xml方式得话需要。
private UserDao userDao;
public void sayHole() {
userDao.sayHole();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
@Qualifier | 根据属性的 名称(用户定义的实例名称或则默认名称)注入要和 @AutoWired一起使用 |
@Repository("ss")
public class UserDao {
public void sayHole() {
System.out.println("sfwefweew");
}
}
@Controller(value = "userTestService")
//value 值可以不写 为生成的对象实例去一个名字。 不写默认为小写
public class UserTestService {
@Autowired
@Qualifier("ss") // 根据类型和名称注入
private UserDao userDao;
public void sayHole() {
userDao.sayHole();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
@Resource | 可以根据 类型输入也可以根据名称注入 |
// @Resource(name = "ss") //根据类型
@Resource(name = "ss") //根据名字
private UserDao userDao;
public void sayHole() {
userDao.sayHole();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
@Value | 注入普通类型属性 |
@Controller(value = "userTestService")
//value 值可以不写 为生成的对象实例去一个名字。 不写默认为小写
public class UserTestService {
// @Autowired
// @Qualifier("ss")
@Resource(name = "ss")
private UserDao userDao;
@Value("注入普通类型属性")
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHole() {
userDao.sayHole();
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
6 完全注解开发
用配置文件类代替xml配置文件实现 零配置文件
1 生成配置文件类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 声明配置文件类 代替xml配置文件
@ComponentScan(basePackages = {"com"})// 配置驱动扫描的包
public class ConfigClass {
}
2 调用方式
@Test
public void test6() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConfigClass.class);
UserTestService userTestService = applicationContext.getBean("userTestService", UserTestService.class);
System.out.println(userTestService.getName());
userTestService.sayHole();
}
2 aop基本原理
1 aop 概述
aop 是 面向切面编程 利用ao可以实现对业务逻辑的各个部分的分割 从而提升开发效率。 降低各个模块间的耦合度 提高重用性 同时提升开发效率。
日志记录,性能统计,安全控制,事务处理,异常处理等等。
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
2 aop底层原理
aop底层使用到了两种动态代理
第一种 有接口的情况 使用jdk动态代理
第二种 没有接口的情况 使用cglb动态代理
jdk 动态代理
1 创建接口
2 创建接口实现类对象
3 创建接口实现类代理对象
cglib代理 没有接口的情况
3 jdk动态代理底层代码实现:
1 使用到的主要类
java.lang.reflect.Proxy;
主要用到的方法 newProxyInstance
2 编写代码
1 创建接口
public interface Work {
public void login();
}
2 接口实现类
public class WorkImp implements Work{
@Override
public void login() {
System.out.println("登录实现======》");
}
}
3 生成被代理类 代理对象
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 创建代理对象方法
public class WorkProxDao implements InvocationHandler {
// 创建被代理对象
private Object object;
public WorkProxDao(Object object) {
this.object = object;
}
// 增强逻辑
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 被增强之前的代码
System.out.println("被增强之前的代码");
// 被增强的代码
Object invoke = method.invoke(object, args);
// 被增强后的代码
System.out.println("被增强后的代码");
return invoke;
}
}
4 调用
@Test
public void test6() {
Class[] interfacse = {Work.class};
WorkImp workImp = new WorkImp();
Work o = (Work)Proxy.newProxyInstance(TestSpring5.class.getClassLoader(), interfacse, new WorkProxDao(workImp));
o.login();
}
3 aop操作中的术语
1 连接点
类里面的那些方法可以被增强 这些方法就称为连接点
2 切入点
实际被增强的方法 称为切入点
3 通知(增强)
实际被增强的部分称为通知
通知类型
1 前置通知
2 后置通知
3 环绕通知
4 异常通知
5 最终通知 finally
4 切面
是动作的操作。 将通知应用切入点的过程。
4 spring实现aop的操作
spring中 使用aspectj实现aop操作
aspectj 是独立的框架 不属于spring
使用方式 xml实现 注解实现
1 准备
1 引入aspectj jar
2 切入点表达式
语法
execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表]))
示例
execution * * com.test.dao login(..)
execution * * com.test.dao *(..) //类中的所有方法增强
execution * * com.test.* *(..) //包中的所有方法增强
2 aspectj注解 实现aop
1 创建被增强类
public class WorkImp implements Work{
@Override
public void login() {
System.out.println("登录实现======》");
}
}
2 创建增强类
// 增强类
public class WorkProx {
//前置通知
public void before() {
}
}
3 进行通知的配置
1 在spring 配置文件中 开启注解扫描
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启spring注解扫描-->
<context:component-scan base-package="com"></context:component-scan>
</beans>
2 使用注解创建user和 userproxy对象
@Component
public class WorkImp {
@Override
public void login() {
System.out.println("登录实现======》");
}
}
// 增强类
@Component
public class WorkProx {
//前置通知
public void before() {
}
}
3 在增强类上面添加注解
// 增强类
@ComponentScan
@Aspect // 生成代理对象注解
public class WorkProx {
//前置通知
public void before() {
}
}
4 spring开启生成代理对象
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启spring注解扫描-->
<context:component-scan base-package="com"></context:component-scan>
<!--开启aspectj注解扫描-->
<aop:scoped-proxy></aop:scoped-proxy>
</beans>
5 配置不同类型的通知
// 增强类
@Component
@Aspect // 生成代理对象注解
public class WorkProx {
//前置通知
@Before(value = "execution(* com.test.dao.WorkImp.login(..))")
public void before() {
System.out.println("前置通知");
}
}
6 测试
@Test
public void test6() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");
WorkImp workImp = applicationContext.getBean("workImp", WorkImp.class);
workImp.login();
}
7 其他类型通知
// 增强类
@Component
@Aspect // 生成代理对象注解
public class WorkProx {
//前置通知
@Before(value = "execution(* com.test.dao.WorkImp.login(..))")
public void before() {
System.out.println("前置通知-------》");
}
//返回通知
@AfterReturning(value = "execution(* com.test.dao.WorkImp.login(..))")
public void afterReturning() {
System.out.println("AfterReturning");
}
// 异常通知
@AfterThrowing(value = "execution(* com.test.dao.WorkImp.login(..))")
public void afterThrowing() {
System.out.println("afterThrowing");
}
// 相同切入点抽取
@Pointcut("execution(* com.test.dao.WorkImp.login(..))") // 切点
public void pointCut() {
}
// 环绕通知
@Around("pointCut()")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("---Around begin---");
proceedingJoinPoint.proceed();
System.out.println("---Around end---");
}
//后置通知
@After(value = "execution(* com.test.dao.WorkImp.login(..))")
public void after() {
System.out.println("后置通知");
}
}
总结:
1、前置通知
在目标方法执行之前执行执行的通知。2、环绕通知
在目标方法执行之前和之后都可以执行额外代码的通知。3、后置通知
在目标方法执行之后执行的通知。4、异常通知
在目标方法抛出异常时执行的通知。5、最终通知
是在目标方法执行之后执行的通知。以上5种都可以额外接收一个JoinPoint参数,来获取目标对象和目标方法相关信息,但一定要保证必须是第一个参数。
五种通知的执行顺序:
1、在目标方法没有抛出异常的情况下
前置通知
环绕通知的调用目标方法之前的代码
目标方法
环绕通知的调用目标方法之后的代码
后置通知
最终通知2、在目标方法抛出异常的情况下
前置通知
环绕通知的调用目标方法之前的代码
目标方法
抛出异常
异常通知
最终通知3、如果存在多个切面
多切面执行时,采用了责任链设计模式。
切面的配置顺序决定了切面的执行顺序,多个切面执行的过程,类似于方法调用的过程,在环绕通知的proceed()执行时,
去执行下一个切面或如果没有下一个切面执行目标方法,从而达成了如下的执行过程:
7 多个增强类对同一个方法的增强 优先级的设置
(1)在增强类中加入注解 @Order(1) 值越小越先执行。
import org.springframework.stereotype.Component;
// 增强类
@Component
@Aspect // 生成代理对象注解
@Order(1)
public class WorkProx
3 基于xml实现aop
1 创建增强类 和被增强类
//创建被增强类
public class Book {
public void sayHole() {
System.out.println("这是一本书");
}
}
// 增强类
public class BookProx {
// 前置通知类型
public void Beafore() {
System.out.println("前置通知类型");
}
}
2 在spring配置文件中创建两个类对象
<bean id="book" class="com.test.service.Book">
</bean>
<bean id="bookProx" class="com.test.service.BookProx">
</bean>
3 在配置文件中配置切入点
<bean id="book" class="com.test.service.Book">
</bean>
<bean id="bookProx" class="com.test.service.BookProx">
</bean>
<!--配置aop增强-->
<aop:config>
<!--切入点-->
<aop:pointcut id="p" expression="execution(* com.test.service.Book.sayHole(..))"></aop:pointcut>
<!--配置切面-->
<aop:aspect ref="bookProx">
<!--曾强作用在具体的方法上-->
<aop:before method="Beafore" pointcut-ref="p"></aop:before>
</aop:aspect>
</aop:config>
4 测试
@Test
public void test6() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean2.xml");
Book book = applicationContext.getBean("book", Book.class);
book.sayHole();
}
<bean id="book" class="com.test.service.Book">
</bean>
<bean id="bookProx" class="com.test.service.BookProx">
</bean>
<!--配置aop增强-->
<aop:config>
<!--切入点-->
<aop:pointcut id="p" expression="execution(* com.test.service.Book.sayHole(..))"></aop:pointcut>
<!--配置切面-->
<aop:aspect ref="bookProx">
<!--曾强作用在具体的方法上-->
<aop:before method="Beafore" pointcut-ref="p"></aop:before>
<aop:after-returning method="After" pointcut-ref="p"></aop:after-returning>
</aop:aspect>
</aop:config>
3 完全注解开发
1 创建配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
// <!--开启spring注解扫描-->
// <context:component-scan base-package="com.test"></context:component-scan>
// 开启扫描驱动
@ComponentScan(basePackages = {"com"})
// <!--开启aspectj注解扫描-->
// <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class configAop {
}
--------------spring核心部分结束
jdbctemplate
1 什么是 jdbctemplate
spring 对jdbctemplate的封装 使用jdbctemplate方便实现对数据库的操作。
2 准备工作
1 引入相关依赖
2 配置spring jdbc数据库连接池
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="jdbc:mysql://116.205.xxxx.8:3306/huawei?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="123456" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
<!-- JdbcTemplate 对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入 dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启spring的注解扫描-->
<context:component-scan base-package="com"></context:component-scan>
</beans>
3 新建dao和service
package com.test.dao;
import com.test.bean.UserBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository("ss")
public class UserDao {
@Autowired
JdbcTemplate jdbcTemplate;
public List<Map<String, Object>> getUser() {
// System.out.println("sfwefweew");
String sql = "SELECT * from `user`";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
return maps;
}
public int add(String username, String age, String sex) {
String sql = "INSERT into `user` (username,age,sex)VALUES(?,?,?)";
int update = jdbcTemplate.update(sql, new Object[]{username, age, sex});
return update;
}
public int add(UserBean userBean) {
String sql = "INSERT into `user` (username,age,sex)VALUES(?,?,?)";
int update = jdbcTemplate.update(sql, new Object[]{userBean.getUsername(), userBean.getAge(), userBean.getSex()});
return update;
}
public int update(UserBean userBean) {
String sql = "update `user` set username=? ,age=?,sex=? where uuid=?";
int update = jdbcTemplate.update(sql, new Object[]{userBean.getUsername(), userBean.getAge(), userBean.getSex(), userBean.getUuid()});
return update;
}
public int delete(UserBean userBean) {
String sql = "delete from `user` where uuid=?";
int update = jdbcTemplate.update(sql, new Object[]{userBean.getUuid()});
return update;
}
// 获取单个值返回
public String getUserName() {
String sql = "SELECT username from `user` where uuid=1";
String s = jdbcTemplate.queryForObject(sql, String.class);
return s;
}
//查询返回对象
public UserBean getUserBean(String uuid) {
String sql = "SELECT * from `user` where uuid=?";
UserBean userBean = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<UserBean >(UserBean.class),uuid);
return userBean;
}
// 返回集合
public List<UserBean> getUserList() {
String sql = "SELECT * from `user` ";
List<UserBean> userBeans = jdbcTemplate.query(sql,new BeanPropertyRowMapper<UserBean >(UserBean.class));
return userBeans;
}
// 批量操作
}
package com.test.service;
import com.test.bean.UserBean;
import com.test.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class Userservice {
@Autowired
UserDao userDao;
public void getUser() {
List<Map<String, Object>> user = userDao.getUser();
}
public void add() {
UserBean userBean = new UserBean();
userBean.setUsername("独腿天天");
userBean.setAge("56");
userBean.setSex("女");
int add = userDao.add("瑞瑞", "12", "女");
}
public int add(UserBean userBean) {
int add = userDao.add(userBean);
return add;
}
public int update(UserBean userBean) {
int add = userDao.update(userBean);
return add;
}
public int delete(UserBean userBean) {
String sql = "delete from `user` where uuid=?";
int delete = userDao.delete(userBean);
return delete;
}
// 获取单个值返回
public String getUserName() {
return userDao.getUserName();
}
//查询返回对象
public UserBean getUserBean(String uuid) {
return userDao.getUserBean(uuid);
}
// 返回集合
public List<UserBean> getUserList() {
return userDao.getUserList();
}
}
4 测试
package com.test;
import com.test.bean.UserBean;
import com.test.service.Userservice;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class TestSpring5 {
@Test
public void test7() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
userservice.getUser();
}
@Test
public void test8() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
userservice.add();
}
@Test
public void test9() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
UserBean userBean = new UserBean();
userBean.setSex("女");
userBean.setAge("123");
userBean.setUsername("ere");
userservice.add(userBean);
}
@Test
public void test10() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
for (int i = 0; i < 100; i++) {
UserBean userBean = new UserBean();
if (i % 2 == 0) {
userBean.setSex("男");
} else {
userBean.setSex("女");
}
userBean.setAge((i % 2 + i) + "");
userBean.setUsername("阿伟" + i);
userservice.add(userBean);
}
}
@Test
public void test11() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
UserBean userBean = new UserBean();
userBean.setSex("男");
userBean.setAge("123");
userBean.setUsername("阿伟");
userBean.setUuid("2");
userservice.delete(userBean);
}
@Test
public void test12() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
String userName = userservice.getUserName();
System.out.println(userName);
}
@Test
public void test13() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
UserBean userBean = userservice.getUserBean("1");
System.out.println(userBean);
}
@Test
public void test14() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
List<UserBean> userList = userservice.getUserList();
System.out.println(userList);
}
}
数据库 批量操作
批量添加
dao
// 批量操作
// 批量添加
public int[] addBatch(List<Object[]> var) {
String sql = "INSERT into `user` (username,age,sex)VALUES(?,?,?) ";
int[] ints = jdbcTemplate.batchUpdate(sql, var);
return ints;
}
// 批量修改
public int[] batchUpdate(List<Object[]> var) {
String sql = "update `user` set username =? ,age=? ,sex= ? where uuid =? ";
int[] ints = jdbcTemplate.batchUpdate(sql, var);
return ints;
}
service
// 批量添加
public int[] addBatch(List<Object[]> var) {
return userDao.addBatch(var);
}
// 批量修改
public int[] batchUpdate(List<Object[]> var) {
return userDao.batchUpdate(var);
}
测试
// 批量添加
@Test
public void test15() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
List<Object[]> var = new ArrayList<>();
for (int i = 0; i < 100; i++) {
//username,age, sex
Object[] objects= new Object[3];
if (i % 2 == 0) {
objects[2]="男";
} else {
objects[2]="女";
}
objects[1]=((i % 2 + i) + "");
objects[0]=("阿伟" + i);
var.add(objects);
}
int[] ints = userservice.addBatch(var);
System.out.println(ints);
}
// 批量添加
@Test
public void test16() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanjdbctemplate.xml");
Userservice userservice = applicationContext.getBean("userservice", Userservice.class);
List<Object[]> var = new ArrayList<>();
for (int i = 0; i < 10; i++) {
//username,age, sex
Object[] objects= new Object[4];
if (i % 2 == 0) {
objects[2]="男";
} else {
objects[2]="女";
}
objects[1]=((i % 2 + i) + "");
objects[0]=("阿伟" + i);
objects[3]=i;
var.add(objects);
}
int[] ints = userservice.batchUpdate(var);
System.out.println(ints);
}