Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由 EJB 框架完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
历史 :
Spring框架的创始人 – Rod Johnson
Rod在悉尼大学不仅获得了计算机学位,同时还获得了音乐学位。
Spring 框架使现有的技术更加容易使用,整合了现有的技术框架

<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.9version>
dependency>
之前的 实例化 dao 接口
private UserDao userDao = new UserDaoImpl();
现在的实例化 dao 接口
private UserDao userDao ;
//使用 set 注入的方式实例化dao接口
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
之前是程序主动创建对象,控制权在程序员手上;现在使用了 set 注入的方式后,程序不在具有主动性,而是变成了被动的接受对象!
这种思想,从本质上解决了问题,程序员不在需要去管理对象的创建了。系统的耦合度大大降低了,可以更专注在业务代码的实现上!这就是 IOC 的原型。
1、导入 maven 依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.9version>
dependency>
2、创建实体类
package com.hkp.entity;
public class User {
private Integer id;
private String name;
private Integer age;
//生成对应的 get、set、toString 方法
}
3、在 resources 文件夹中创建 applicationContext.xml 文件
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.hkp.entity.User">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
bean>
beans>
4、创建测试类
public static void main(String[] args) {
//家在配置文件,实例化一个容器,获取Spring的上下文对象,参数可以有多个(可以加载多个配置文件)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//我们的对象现在都在 Spring 容器中管理,如果要使用,只需要从里面取出来就行
//从 Spring 容器中取对象 ,参数为 对象名 -- 就是 applicationContext.xml 文件中 bean 标签中的 name 属性
User user = (User) context.getBean("user");
System.out.println(user.toString());
//输出结果 :User{id=1, name='admin', age=21}
}
思考问题 :
1、谁创建的对象? --Spring 创建的
2、对象的属性是怎么设置的? --属性是有 Spring 容器设置的
这个过程就叫控制反转。
控制 :谁来控制对象的创建?传统的应用程序的对象是由程序本身控制创建的(new出一个对象),使用 Spring 后,对象是由 Spring 来创建的。
反转 :程序本身不创建对象,而是被动的接收对象。
依赖注入 :就是利用 set 方法进行注入。
IOC 是一种编程思想,由主动的编程变成被动的接收。
现在,要实现的操作,我们彻底不用去程序中做改动。只需要在 xml 配置文件中进行修改。
所谓的 IOC 就是一句话 :对象由 Spring 来创建、管理、装配。
1、默认使用 无参构造器 创建对象,默认的方式
<bean id="user" class="com.hkp.entity.User">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
bean>
2、使用有参构造器创建对象,
通过下标赋值,下标的顺序就是参数的顺序,不能颠倒顺序
<bean id="user" class="com.hkp.entity.User">
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="admin"/>
<constructor-arg index="2" value="21"/>
bean>
通过参数名赋值(与无参构造器类似)
<bean id="user" class="com.hkp.entity.User">
<constructor-arg name="id" value="1"/>
<constructor-arg name="name" value="admin"/>
<constructor-arg name="age" value="21"/>
bean>
总结 :在配置文件被加载的时候,容器中管理的对象(bean)就已经被初始化了。
方式一 :使用 alias 标签定义
<alias name="user" alias="newUser"/>
//实例化一个容器,获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("newUser");
System.out.println(user.getName().equals(user2.getName()));//true
方式二 :使用 bean 标签定义
<bean id="user" class="com.hkp.entity.User" name="user2,user3 user4;user5">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
bean>
这个标签用于团队开发使用,他可以将多个配置文件,导入合并为一个。
多个配置文件中的配置有相同的配置的话,在调用的时候会随机选择一个进行使用
1、在 resources 文件夹中创建 beans.xml 、beans2.xml 文件,内容相同
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.hkp.entity.User" name="user2,user3 user4;user5">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
bean>
beans>
2、applicationContext.xml
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
beans>
3、测试
public static void main(String[] args) {
//实例化一个容器,获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//我们的对象现在都在 Spring 容器中管理,如果要使用,只需要从里面取出来就行
//从 Spring 容器中取对象 ,参数为 对象名 -- 就是 applicationContext.xml 文件中 bean 标签中的 name 属性
User user = (User) context.getBean("user");
System.out.println(user.toString());
//输出结果 :User{id=1, name='admin', age=21}
}
依赖 :bean 对象的创建依赖于容器
注入 :bean 对象中的所有属性,由容器来注入
DI 存在两种主要变体:基于构造函数的依赖注入和基于 Setter 的依赖注入。
在 IOC 创建对象的方式中已经讲过了。
通过下标赋值,下标的顺序就是参数的顺序,不能颠倒顺序
<bean id="user" class="com.hkp.entity.User">
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="admin"/>
<constructor-arg index="2" value="21"/>
bean>
通过参数名赋值(与无参构造器类似)
<bean id="user" class="com.hkp.entity.User">
<constructor-arg name="id" value="1"/>
<constructor-arg name="name" value="admin"/>
<constructor-arg name="age" value="21"/>
bean>
案例 :
1、创建实体类
真实测试的实体类
public class User {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> score;
private Set<String> games;
private String testNull;
private String testKong;
private Properties pro;
//对应的 get、set和 toString 方法
}
引用类型的实体类
package com.hkp.entity;
public class Address {
private String address;
//对应的 get、set和 toString 方法
}
配置 applicationContext.xml
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.hkp.entity.Address">
<property name="address" value="北京市"/>
bean>
<bean id="user" class="com.hkp.entity.User">
<property name="name" value="admin"/>
<property name="address" ref="address"/>
<property name="books">
<array>
<value>水浒传value>
<value>西游记value>
<value>红楼梦value>
<value>三国演义value>
array>
property>
<property name="hobbies">
<list>
<value>听歌value>
<value>读书value>
<value>敲代码value>
list>
property>
<property name="score">
<map>
<entry key="语文" value="96"/>
<entry key="数学" value="99"/>
<entry key="英语" value="90"/>
map>
property>
<property name="games">
<set>
<value>LOLvalue>
<value>BOBvalue>
<value>吃鸡value>
set>
property>
<property name="testNull">
<null/>
property>
<property name="testKong" value=""/>
<property name="pro">
<props>
<prop key="学号">20210210prop>
<prop key="姓名">adminprop>
<prop key="性别">男prop>
props>
property>
bean>
beans>
测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user.toString());
/*
* User{
* name='admin',
* address=Address{address='北京市'},
* books=[水浒传, 西游记, 红楼梦, 三国演义],
* hobbies=[听歌, 读书, 敲代码],
* score={语文=96, 数学=99, 英语=90},
* games=[LOL, BOB, 吃鸡],
* testNull='null',
* testKong='',
* pro={学号=20210210, 性别=男, 姓名=admin}
* }
* */
}
在 applicationContext.xml 文件中添加
xmlns:p="http://www.springframework.org/schema/p"
applicationContext.xml
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.hkp.entity.User" p:id="1" p:age="21" p:name="admin" p:address-ref="address"/>
<bean id="address" class="com.hkp.entity.Address">
<property name="address" value="北京市"/>
bean>
beans>
在 applicationContext.xml 文件中添加
xmlns:c="http://www.springframework.org/schema/c"
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user2" class="com.hkp.entity.User" c:id="1" c:age="21" c:name="admin" c:address-ref="address"/>
<bean id="address" class="com.hkp.entity.Address">
<property name="address" value="北京市"/>
bean>
beans>
是 Spring 的默认机制
<bean id="user" class="com.hkp.entity.User" scope="singleton"/>
在 调用的时候,同时调用两次返回的结果是相同的,就说明两次调用的bean 是同一个 bean
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);//true
System.out.println(user.hashCode());//827966648
System.out.println(user2.hashCode());//827966648
每次从容器中 getBean 的时候都会产生一个新对象
<bean id="user" class="com.hkp.entity.User" scope="prototype"/>
在 调用的时候,同时调用两次返回的结果不是相同的,就说明两次调用的bean 不是同一个 bean
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);//false
System.out.println(user.hashCode());//1164371389
System.out.println(user2.hashCode());//517210187
其余的作用域 request、session、application 等都是 web 的时候才能用到
自动装配是 Spring 满足 bean 依赖的一种方式,Spring 会在上下文中自动寻找,并自动给 bean 装配属性!
Spring 中有三种装配方式 :
实体类
//cat
public class Cat {
public void shout(){
System.out.println("miao~");
}
}
//dog
public class Dog {
public void shout(){
System.out.println("wang~");
}
}
//People
public class People {
private Cat cat;
private Dog dog;
private String name;
//对应的 get、set 方法
}
xml
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<bean id="people" class="com.hkp.entity.People">
<property name="name" value="test"/>
<property name="dog" ref="dog"/>
<property name="cat" ref="cat"/>
bean>
beans>
测试类
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
People people = context.getBean("people", People.class);
people.getDog().shout();
people.getCat().shout();
}
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<bean id="people" class="com.hkp.entity.People" autowire="byName">
<property name="name" value="test"/>
bean>
beans>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<bean id="people" class="com.hkp.entity.People" autowire="byType">
<property name="name" value="test"/>
bean>
beans>
小结 :
jdk 从1.5开始支持注解,Spring 从 2.5 开始支持注解
1、导入约束
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"
2、在 applicationContext.xml 中配置 注解的支持
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<bean id="people" class="com.hkp.entity.People">
<property name="name" value="test"/>
bean>
beans>
People 实体中的改动
public class People {
@Autowired
@Qualifier(value = "cat1")
private Cat cat;
@Autowired
private Dog dog;
private String name;
//对应的 get 的方法
}
@Autowired
import org.springframework.beans.factory.annotation.Autowired;
该注解可以直接加在属性或者 set 方法上;使用该注解时,实体类中可以不加 set 方法
@Qualifier(value = “cat1”)
import org.springframework.beans.factory.annotation.Qualifier;
该注解用于一个对象在 applicationContext.xml 配置文件中配置了多个bean,此时自动注入不知该选择哪一个,这时用该注解来指定一个 bean 即可。value 的参数值为 bean 标签中的 id 值
@Resource
import javax.annotation.Resource;
public class People {
@Resource
private Cat cat;
@Resource
private Dog dog;
private String name;
//对应的 get 方法
}
该注解的作用可以替代@Autowired 和 @Qualifier(value = “cat1”) 他们两个,如果不加参数就和@Autowired 类似。 如果一个对象在 application.xml 配置文件中配置了多个bean,此时直接使用 @Resource 自动注入不知该选择哪一个,这时在该注解后面加一个参数 @Resource(name = “”) 指定一个 bean 即可。name 的值为 bean 标签中的 id 值
@Autowired 和 @Resource 的区别 :
在 Spring4 之后 要使用注解开发,需要导入 aop 包

在 applicationContext.xml 配置文件中配置注解的支持
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.hkp"/>
beans>
import org.springframework.stereotype.Component;
组件,用在实体类上,等价于在xml文件中 ,id属性默认为全小写
1、创建实体类
@Component //组件,等价于在xml文件中 ,id属性默认为全小写
public class User {
public String name="Hello World!!!";
}
2、编写测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);
System.out.println(user.name);
}
import org.springframework.beans.factory.annotation.Value;
给属性设置默认值,相等于
1、编写实体类
@Component //组件,等价于在xml文件中
public class User {
//给属性默认值,相等于
@Value("Hello World!!!")
public String name;
}
2、编写测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);
System.out.println(user.name);
}
@Component 中有几个衍生的注解,这几个注解的作用都是一样的,都是用来将类注解成bean 的,只不过用的层级不一样
dao
import org.springframework.stereotype.Repository;
@Repository
service
import org.springframework.stereotype.Service;
@Service
controller
import org.springframework.stereotype.Controller;
@Controller
小结 :
@Component 实体类
@Repository 持久层
@Service 业务层
@Controller 控制层
@Autowired
import org.springframework.beans.factory.annotation.Autowired;
该注解可以直接加在属性或者 set 方法上;使用该注解时,实体类中可以不加 set 方法
@Qualifier(value = “cat1”)
import org.springframework.beans.factory.annotation.Qualifier;
该注解用于一个对象在 applicationContext.xml 配置文件中配置了多个bean,此时自动注入不知该选择哪一个,这时用该注解来指定一个 bean 即可。value 的参数值为 bean 标签中的 id 值
@Resource
import javax.annotation.Resource;
public class People {
@Resource
private Cat cat;
@Resource
private Dog dog;
private String name;
//对应的 get 方法
}
该注解的作用可以替代@Autowired 和 @Qualifier(value = “cat1”) 他们两个,如果不加参数就和@Autowired 类似。 如果一个对象在 application.xml 配置文件中配置了多个bean,此时直接使用 @Resource 自动注入不知该选择哪一个,这时在该注解后面加一个参数 @Resource(name = “”) 指定一个 bean 即可。name 的值为 bean 标签中的 id 值
@Autowired 和 @Resource 的区别 :
import org.springframework.context.annotation.Scope;
@Component //组件,等价于在xml文件中
@Scope("singleton")
//@Scope("singleton") 表示将该实体设置生了单例模式,Spring的默认模式
//@Scope("prototype") 表示将该实体设置生了原型模式,每次从容器中 getBean 的时候都会产生一个新对象
public class User {
//给属性默认值,相等于
@Value("Hello World!!!")
public String name;
}
可以不使用 xml 来配置 Spring 了,
1、创建实体
package com.hkp.entity;
import org.springframework.beans.factory.annotation.Value;
public class User {
@Value("hello")
private String name;
//get、set方法
}
2、创建配置文件
package com.hkp.config;
import com.hkp.entity.User;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
@Configurable //等同于 applicationContext.xml 文件中的 标签
@Import(MyConfig2.class)//引入外部配置文件,等价于
public class MyConfig {
/**
* 注册一个bean,等价于在xml文件中
* 方法中的方法名相当于 bean 标签中的id属性
* 方法中的返回值相当于 bean 标签中的 class 属性
* @return
*/
@Bean
public User getUser(){
return new User();
}
}
3、创建测试
import com.hkp.config.MyConfig;
import com.hkp.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestDemo {
public static void main(String[] args) {
//如果使用了配置类方式去做,我们就只能通过AnnotationConfigApplicationContext 来获取容器
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User) context.getBean("getUser");
System.out.println(user.getName());
}
}
代理模式是SpringAOP的底层
代理模式的分类 :
代理模式的好处 :
缺点 :
以一个 租房的案例 :
1、编写接口
public interface Rent {
void rent();
}
2、真实角色(房东)
public class Host implements Rent{
public void rent(){
System.out.println("房主要出租房子");
}
}
3、代理
public class Proxy implements Rent{
//出租房间
@Override
public void rent() {
look();
System.out.println("授权给代理发布房间出租");
free();
}
//收中介费
public void free(){
System.out.println("收中介费");
}
//看房子
public void look(){
System.out.println("看房子");
}
}
4、客户端访问代理角色
public class Client {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.rent();
}
}
动态代理的代理类是动态生成的,不是我们直接写好的
动态代理分为两类 :
JDK 动态代理需要用到的类 :Proxy :代理、InvocationHandler :调用处理程序(里面只有一个方法 invoke )
1、编写接口
public interface Rent {
void rent();
}
2、真实角色(房东)
public class Host implements Rent{
public void rent(){
System.out.println("房主要出租房子");
}
}
3、动态生成代理类
package com.hkp.demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//用这个类,自动生成代理类
public class ProxyIn implements InvocationHandler {
//需要被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
//执行方法
Object result = method.invoke(rent, args);
free();
return result;
}
public void seeHouse(){
System.out.println("看房子");
}
public void free(){
System.out.println("收中介费");
}
}
4、客户端访问代理角色
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//获得代理类
ProxyIn proxyIn = new ProxyIn();
proxyIn.setRent(host);
//动态生成的代理类
Rent proxy = (Rent) proxyIn.getProxy();
proxy.rent();
}
}
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
提供声明式事务,允许用户自定义切面
横切关注点 :跨越应用程序多个模块的方法或功能。即与我们的业务逻辑无关,但需要我们关注的部分,就是横切关注点。如日志、事务、缓存等等。
切面(ASPECT):横切关注点被模块化的特殊对象。即他是一个类
通知(Advice):切面必须要完成的工作。即他是类中的一个方法
目标(Target):被通知的对象
代理(Proxy):向目标对象应用通知之后创建的对象
切入点(PointCut):切面通知执行的“地点”
连接点(JoinPoint):与切入点匹配的执行点

Spring AOP 中,通过Advice 定义横切逻辑,Spring 中支持类型的 Advice

需要的依赖
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.7version>
dependency>
1、创建接口
package com.hkp.service;
public interface UserService {
void add();
void delete();
void update();
void select();
}
2、创建接口实现
package com.hkp.service;
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("进入了增加方法");
}
@Override
public void delete() {
System.out.println("进入了删除方法");
}
@Override
public void update() {
System.out.println("进入了修改方法");
}
@Override
public void select() {
System.out.println("进入了查询方法");
}
}
3、创建日志类
//前置通知
package com.hkp.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class BeforeLog implements MethodBeforeAdvice {
/**
* 参数详解
* @param method 执行的方法
* @param objects 参数
* @param o 目标对象
* @throws Throwable
*/
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName()+"类中的 "+method.getName()+" 方法即将被执行");
}
}
//后置通知
package com.hkp.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
/**
*
* @param o 返回值
* @param method 执行的方法
* @param objects 参数
* @param o1 目标对象
* @throws Throwable
*/
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println(o1.getClass().getName()+"类中的 "+method.getName()+" 方法已经被执行");
}
}
4、配置 applicationContext.xml 文件
导入约束
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
<bean id="afterLog" class="com.hkp.log.AfterLog"/>
<bean id="beforeLog" class="com.hkp.log.BeforeLog"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.hkp.service.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
aop:config>
beans>
5、测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userServiceImpl");
userService.add();
}
接口与实现类与方式一中的相同
1、编写 自定义日志类
package com.hkp.diy;
public class DiyPointCut {
public void before(){
System.out.println("执行方法前");
}
public void after(){
System.out.println("执行方法后");
}
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
jp.proceed();//执行方法
System.out.println("环绕后");
}
}
2、配置 applicationContext.xml 文件
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
<bean id="diy" class="com.hkp.diy.DiyPointCut"/>
<aop:config>
<aop:aspect ref="diy">
<aop:pointcut id="point" expression="execution(* com.hkp.service.UserServiceImpl.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
<aop:around method="around" pointcut-ref="point"/>
aop:aspect>
aop:config>
beans>
3、测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userServiceImpl");
userService.add();
}

接口与实现类与方式一中的相同
1、编写 自定义日志类
package com.hkp.diy;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect //标注该类是一个切面类
public class AnnoPointCut {
//里面的参数为切入点
@Before("execution(* com.hkp.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("执行方法前");
}
@After("execution(* com.hkp.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("执行方法后");
}
}
2、配置 applicationContext.xml 文件
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
<bean id="annoPointcut" class="com.hkp.diy.AnnoPointCut"/>
<aop:aspectj-autoproxy/>
beans>
3、测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userServiceImpl");
userService.add();
}
文档 :mybatis-spring –

<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.9version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.3.9version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.7version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.20version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.25version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.6version>
dependency>
1、创建 mybatis 核心配置文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">properties>
<typeAliases>
<package name="com.hkp.entity"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
dataSource>
environment>
environments>
<mappers>
<mapper class="com.hkp.mapper.UserMapper"/>
mappers>
configuration>
2、创建实体类
package com.hkp.entity;
import java.util.Date;
public class User {
private Integer id;
private String userCode;
private String userName;
private String userPassword;
private Integer gender;
private Date birthday;
private String phone;
private String address;
private Integer userRole;
private Integer createdBy;
private Date creationDate;
private Integer modifyBy;
private Date modifyDate;
...对应的 get set 方法
}
3、创建 UserMapper 接口
public interface UserMapper {
List<User> selectUser();
}
4、创建 UserMapper.xml 映射器
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hkp.mapper.UserMapper">
<select id="selectUser" resultType="user">
SELECT * FROM smbms_user
select>
mapper>
5、创建 测试类
@Test
public void testMybatis() throws Exception{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.selectUser();
sqlSession.close();
for (User user: userList) {
System.out.println(user);
}
}
1、修改 mybatis 核心配置文件的配置
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.hkp.entity"/>
typeAliases>
configuration>
2、创建 UserMapper 实现
package com.hkp.mapper;
import com.hkp.entity.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper{
//之前都是使用 sqlSession 来操作,现在是使用 sqlSessionTemplate
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
return sqlSession.getMapper(UserMapper.class).selectUser();
}
}
3、创建 spring 配置文件
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder
location="classpath*:db.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}">property>
<property name="url" value="${url}">property>
<property name="username" value="${user}">property>
<property name="password" value="${password}">property>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/hkp/mapper/*.xml"/>
bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
bean>
<bean id="userMapper" class="com.hkp.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
bean>
beans>
4、编写测试类
@Test
public void testSpring(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dataSource.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> userList = userMapper.selectUser();
for (User user: userList) {
System.out.println(user);
}
}
SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法
1、重新创建 UserMapper 实现类
public class UserMapper2 extends SqlSessionDaoSupport implements UserMapper {
@Override
public List<User> selectUser() {
SqlSession sqlSession = getSqlSession();
return sqlSession.getMapper(UserMapper.class).selectUser();
}
}
2、修改 spring 的配置文件
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder
location="classpath:db.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}">property>
<property name="url" value="${url}">property>
<property name="username" value="${user}">property>
<property name="password" value="${password}">property>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/hkp/mapper/*.xml"/>
bean>
<bean id="userMapper2" class="com.hkp.mapper.UserMapper2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
bean>
beans>
3、编写测试
@Test
public void testSpring(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dataSource.xml");
UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
List<User> userList = userMapper.selectUser();
for (User user: userList) {
System.out.println(user);
}
}
声明式事务 :可以在不改变原有的代码,添加事务。
事务的 ACID 原则 :
1、在 applicationContext.xml 中引入事务约束 (tx)
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
2、创建 bean
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg name="dataSource" ref="dataSource" />
bean>
3、结合AOP 实现事务
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add"/>
<tx:method name="delete"/>
<tx:method name="update"/>
<tx:method name="query"/>
<tx:method name="*"/>
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut id="txPoint" expression="execution(* com.hkp.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
aop:config>
4、测试插入和删除代码
package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
@Override
public List<User> selectUser() {
User user = new User("admin","123",1);
int i = this.addUser(user);
int i1 = this.deleteUser(22);
SqlSession sqlSession = getSqlSession();
return sqlSession.getMapper(UserMapper.class).selectUser();
}
@Override
public int addUser(User user) {
return getSqlSession().getMapper(UserMapper.class).addUser(user);
}
@Override
public int deleteUser(int id) {
return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
}
}