文章目录
首先,感谢一下@狂神老师的Spring课程https://www.bilibili.com/video/BV1WE411d7Dv?spm_id_from=333.999.0.0
其次,感谢一下@黑心白莲同学的笔记https://blog.csdn.net/li643937579/article/details/109569887
前言:这一阶段的学习,主要注重思想上的学习,重点关注的是IOC和AOP,以及静态代理或者动态代理设计模式的学习
1、Spring概述
1.1 简介
- spring:春天:也就是说给软件行业带来了春天
- 官网 : http://spring.io/
- 官方的参考文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-scopes
1.2 优点
- Spring是一个开源免费的框架、容器
- Spring是一个轻量级的框架 , 非侵入式的
- Spring的核心就是IOC和AOP
1.3 IOC
- 控制翻转。通俗的来讲就是创建对象的方式不同,不用创建对象了,通过bean,已经Spring的容器技术自动的对其进行装配
1.4 APO
- 面向切面编程
- 通过使用Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中
1.5 拓展
Springboot和Spring Cloud
- Spring boot 是Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务
- Spring Cloud是基于Spring Boot实现的
- SpringBoot在SpringClound中起到了承上启下的作用,如果要学习SpringCloud必须要学习 SpringBoot
- 同样的道理,学习Springboot首先需要学习Spring 和SpringMVC(过度的承上启下作业)
2、IOC基础
2.1 需要的依赖包
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--junit测试工具包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<!--使用AOP织入,需要导入一个依赖包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
2.2 IOC的本质
-
以前程序是主动创建对象,控制权在业务层,也就是在程序员的手上
-
-
现在可以交出程序的控制权,到用户的手上
- -
IOC本质
个人认为控制反转就是:获得依赖对象的方式变了
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
3、HelloSpring
对应程序是 Spring-02-hello
1. 新建一个Maven项目,编写实体类
package com.qin.dao;
public class Hello {
private String str;
public String getStr() {
return str;
}
// spring 本质上是通过set方法进行注入的
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
2. 编写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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
使用Spring来创建对象,在Spring中这些称为Bean
类型 变量名 = new 类型();
id 相当于一个变量名
class =new 一个对象
property 相当于给对象中的属性设置一个值!
-->
<bean id="hello" class="com.qin.dao.Hello">
<property name="str" value="Spring!!!"/>
</bean>
</beans>
3. 测试
import com.qin.dao.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 第一步CPX 加载XML的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 第二步 getbean 获取bean的对象
Hello hello = (Hello) context.getBean("hello");
// 打印输出结果
System.out.println(hello.toString());
}
}
思考问题:
- Hello对象由谁创建?(Spring创建的)
- Hello对象的属性是怎么设置的?(Spring的容器设置的)
这个过程就叫做控制反转
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
反转:程序本身不创建对象,而变成被动的接收对象。
依赖注入:就是利用set方法来进行注入的。
OK,到了现在,我们彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配!
总结:所谓的IOC是,对象由Spring来创建,管理和装配!
4、IOC创建对象的方式
对应的程序Spring-02-IOC
4.1 使用无参构造函数创建对象,默认的方式
1. User类
package com.qin.dao;
public class User {
private String name;
public User(){
System.out.println("User的无参构造函数");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
2、UserT类
package com.qin.dao;
public class UserT {
private String name;
public UserT(String name){
this.name = name;
System.out.println("UserT的有参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
3.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
使用Spring来创建对象,在Spring中这些称为Bean
类型 变量名 = new 类型();
id 相当于一个变量名
class =new 一个对象
property 相当于给对象中的属性设置一个值!
-->
<!-- bean在创建对象的时候,默认调用无参的构造函数
如果调用有参的构造函数,需要换一种方法初始化
-->
<bean id="user" class="com.qin.dao.User">
<property name="name" value="qinqs"/>
</bean>
<!-- 有参的构造函数,bean初始化对象 注意:属性的赋值的方式不一样-->
<bean id="userT" class="com.qin.dao.UserT">
<constructor-arg name="name" value="qinqsTTT"/>
</bean>
<!-- 总结:
在beans.xml配置文件加载的时候,容器中管理的对象就已经初始化了!
-->
4. 测试类
import com.qin.dao.User;
import com.qin.dao.UserT;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user = context.getBean("user", User.class);
user.show();
// UserT userT = (UserT) context.getBean("userT");
// userT.show();
}
}
4.2 使用有参构造创建对象的时候
- 注意:在bean给属性赋值的时候,选用的参数不一样
- 通过实验分析可以得出一个结论:在XML配置文件加载的时候,容器中管理的对象就自动的创建了。
5、Spring的配置
5.1 别名
<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="userT" alias="userNew"/>
5.2 Bean的配置
<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
5.3 import
- 团队的协同开发中可以用到这个功能
- 命名applicationContext.xml (使用的时候,直接调用这个配置就可以了)
<import resource="bean.xml"/>
<import resource="bean2.xml"/>
<import resource="bean3.xml"/>
6、依赖注入(DI)
对应的练习程序为Spring-04-ID
- 依赖注入(Dependency Injection,DI)
- 依赖:指Bean对象的创建依赖于容器
- 注入:指Bean对象所需要依赖的资源,由容器来设置和装配
6.1 构造器注入
- 4中IOC创建对象的方式(有参构造已经用过了)
<bean id="userT" class="com.qin.dao.UserT">
<constructor-arg name="name" value="qinqsTTT"/>
</bean>
6.2 set注入(重点)
-
要求被注入的属性,必须有set方法
-
测试的pojo类(注意,要注入的熟悉中,都有需要的set方法)
Address.class
package com.qin.pojo; public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } }
Student.class
package com.qin.pojo; import java.util.*; public class Student { private String name; private Address address; private String[] books; private List<String> hobbies; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List<String> getHobbies() { return hobbies; } public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; } public Map<String, String> getCard() { return card; } public void setCard(Map<String, String> card) { this.card = card; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public String getWife() { return wife; } public void setWife(String wife) { this.wife = wife; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", address=" + address + ", books=" + Arrays.toString(books) + ", hobbies=" + hobbies + ", card=" + card + ", games=" + games + ", wife='" + wife + '\'' + ", info=" + info + '}'; } }
Mytest.class 测试类
import com.qin.pojo.Student; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.toString()); } }
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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="com.qin.pojo.Address"> <property name="address" value="兰州"/> </bean> <bean id="student" class="com.qin.pojo.Student"> <!--第一种,普通值注入--> <property name="name" value="秦"/> <!--第二种,bean注入--> <property name="address" ref="address"/> <!--数组注入--> <property name="books"> <array> <value>红楼梦</value> <value>西游记</value> <value>三国演义</value> <value>水浒传</value> </array> </property> <!--list注入--> <property name="hobbies"> <list> <value>打篮球</value> <value>踢足球</value> <value>敲代码</value> </list> </property> <!--map注入--> <property name="card"> <map> <entry key="身份证" value="1234"></entry> <entry key="银行卡" value="789456"></entry> </map> </property> <!--set注入--> <property name="games"> <set> <value>LOLO</value> <value>CCO</value> </set> </property> <!--null注入--> <property name="wife"> <null></null> </property> <!--Properties--> <property name="info"> <props> <prop key="urel">123</prop> <prop key="pass">hhhhh</prop> </props> </property> </bean> </beans>
6.3 拓展方式注入(p命名空间和c命名空间)
- P 命名空间的注入和C命名空间的使用,需要引入约束文件
- P命名空间,适用于无参构造,对应properties
- C命名空间,适用于有参构造,对应于Constructor
<?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:p="http://www.springframework.org/schema/p"
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">
<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="com.kuang.pojo.User" p:name="qin" p:age="20"/>
<!--c命名空间注入,通过构造器注入:constructor-args-->
<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22"/>
</beans>
6.4 Bean 的作用域
-
singleton单例模式(Spring默认的机制)
<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="singleton"/>
单例模型,每次产生的对象都是一样的
-
prototyper原型模型
<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="prototype"/>
每次从容器中getbean的时候,都会产生一个新的对象
7、Bean的自动装配(重点)
对应的练习程序为Spring-05-auto
- 自动装配是Spring满足bean依赖的一种方式
- Spring会在上下文中自动寻找,并给bean装配属性
在Spring中有三种装配的方式:
1. 在XML中显示的配置
1. 在java中显示的配置
1. 饮食的自动装配bean【重要】
7.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"
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="cat" class="com.qin.pojo.Cat"></bean>
<bean id="dog" class="com.qin.pojo.Dog"></bean>
<bean id="user" class="com.qin.pojo.User" >
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
<property name="name" value="qin"/>
</bean>
</beans>
7.2 ByName自动装配
- autowire byName(按名称自动装配)
<?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
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/>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
-->
<bean id="cat" class="com.qin.pojo.Cat"></bean>
<bean id="dog" class="com.qin.pojo.Dog"></bean>
<bean id="user" class="com.qin.pojo.User" autowire="byName">
<property name="name" value="qin"/>
</bean>
</beans>
7.3 ByType自动装配
- autowire byType(按类型自动装配)
<?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
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/>
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
必须保证全局唯一!!!
-->
<bean id="cat" class="com.qin.pojo.Cat"></bean>
<bean id="dog" class="com.qin.pojo.Dog"></bean>
<bean id="user" class="com.qin.pojo.User" autowire="byType">
<property name="name" value="qin"/>
</bean>
</beans>
小结:
- ByName的时候,会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
- ByType的时候,会自动在容器上下文中查找,和自己对象属性类型相同的bean!且必须保证全局唯一!!!
7.4 使用注解实现自动装配
-
jdk1.5支持的注解,Spring2.5就支持注解了!
-
使用注解开发的时候,需要导入约束的头文件,并开启注解的支持!需要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 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/> </beans>
-
在大部分的情况下,我们都会选用注解开发,尤其是在后期的SpringBoot中
-
Autowired的注解
- xml的配置只需要开启支持注解,然后注册bean,会变的非常的干净
<?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 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="cat" class="com.qin.pojo.Cat"></bean> <bean id="dog" class="com.qin.pojo.Dog"></bean> <bean id="user" class="com.qin.pojo.User"></bean> </beans>
- User.class
package com.qin.pojo; import org.springframework.beans.factory.annotation.Autowired; public class User { // Autowired的注解,在属性上可以使用,在set方法上也可以直接使用 // 使用Autowired的注解,本质上利用的是反射的实现,连set方法也可以省略不要 // 使用Autowired的注解,XML配置可以变的很干净,只需要注册bean,不需要装配属性 @Autowired // Autowired的注解,在属性上 private Cat cat; @Autowired private Dog dog; private String name; public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "com.qin.pojo.User{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
- 使用Autowired我们就可以不用编写set方法了,前提是你这个自动配置的属性在IOC(Spring)容器中存在,且符合名字byName!(本质上是,使用byType自动进行装配的!!!)
-
Qualifier注解(不能单独使用,必须配合autowire的注解使用)
-
如果@Autowired自动装配的时候环境比较复杂,自动装配无法通过一个注解【@Autowired】来完成的时候【本质上是通过byType来完成的注解】,我们可以通过【@Qualifier(value=“xxx”)】来配合@Autowired的使用
-
本质:@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配;@Qualifier不能单独使用。
-
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: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="cat" class="com.qin.pojo.Cat"></bean> <bean id="dog" class="com.qin.pojo.Dog"></bean> <bean id="dog1" class="com.qin.pojo.Dog"></bean> <bean id="dog2" class="com.qin.pojo.Dog"></bean> <bean id="user" class="com.qin.pojo.User"></bean> </beans>
-
User.calss
package com.qin.pojo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class User { // Autowired的注解,在属性上可以使用,在set方法上也可以直接使用 // 使用Autowired的注解,本质上利用的是反射的实现,连set方法也可以省略不要 // 使用Autowired的注解,XML配置可以变的很干净,只需要注册bean,不需要装配属性 @Autowired // Autowired的注解,在属性上 private Cat cat; @Autowired @Qualifier(value = "dog1") // Qualifier注解配合Autowired注解的使用,来增强bean的自动装配 private Dog dog; private String name; public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "com.qin.pojo.User{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
-
-
Resource注解
-
Resource注解的使用,也是直接放在属性的字段上面
@Resource private Cat cat; @Resource private Dog dog; private String name;
-
Autowired和Resource的区别
- 相同点:都是用来实现bean的自动装配的
- 区别1:Autowired通过byType的方式实现,而且必须要求这个对象存在,如果遇到复杂的情况,可以配合Qualifier注解来使用。【常用】
- 区别2:Resource默认通过byName的方式实现,如果找不到名字,则自动的通过byType的方式实现,如果两个都找不到,则就报错。需要注意的是,如果name属性一旦指定,就只会按照名称ByName进行装配。【常用】
-
7.5 小结
- @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或set方法上。
- 它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先 byName(Resource的功能更加的强大)。
- @Autowired 是Spring的注解 ,@Resource 是java的注解
8、使用注解开发(重点)
对应的练习程序为:Spring-06-anno
使用注解开发,必须导入AOP包,同时使用注解的时候,要在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: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.qin.pojo"/>
<context:annotation-config/>
<!--开启注解驱动的支持-->
</beans>
-
bean(@Component注解来注册bean)
package com.qin.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; // 这个注解就等价于 <bean id="user" class="com.qin.pojo.User"> // @Component 代表的是组件 @Component // 一般情况下放在类上,说明这个类被Spring管理了 public class User { @Value("哈哈") // 这个等价于属性的注入 <property name="name" value="秦疆"/> public String name; }
-
属性如何注入
// 这个注解就等价于 <bean id="user" class="com.qin.pojo.User"> // @Component 代表的是组件 @Component public class User { @Value("哈哈") // 这个等价于属性的注入 <property name="name" value="秦疆"/> public String name; }
-
衍生的注解
@Component的有几个衍生的注解,我们在web的开发中,会按照MVC三成架构来进行分层
-
dao层【@Repository】
-
service层【@Service】
-
web层【@Controller】
这四个注解的功能都是一样的,都是将某个类注册到Spring中的容器中,进行装配
-
-
自动装配
- @Autowired
- @Qualifier
- @Resource
-
作用域
- @Scope(“singleton”) 有单例模式和原型模式
-
XML和注解
- XML更加的万能,适用于任何场合,维护简单方便!
- 注解不是自己的类使用不了,维护相对复杂!
- 最佳实践:
- xml用来管理bean
- 注解只负责完成属性的注入
- 我们在使用的过程中,只需要注意一个问题,必须让注解生效,就需要开启注解的支持
9、使用Java的方式配置Spring
对应的练习程序为:Spring-07-anno2
本质上,使用的还是注解
现在我们完全不使用XML进行配置了,全权交给Java来进行配置
本质就是:用一个配置类来代替原来的XML来实现bean的注册的装配
User.class
package com.qin.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
// 注解的意思是,说明这个类完全呗Spring接管了,注册到容器中了
@Component
public class User {
@Value("qin") // 给属性注入值
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
Myconfig.class
package com.qin.config;
import com.qin.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 现在我们完全不需要Spring的xml配置信息了,全权交给Java来做
// @Configuration 代表的这是一个配置类,和原来的beans.xml道理一样
@Configuration
public class Myconfig {
@Bean // 注册一个bean 方法的名字就相当于bean标签中的id属性
public User user(){
return new User();
// 返回值相当于bean标签中的class属性
}
// 总结:这种用java来接管的配置,在SpringBoot中随处可见
}
Mytest.class测试类
import com.qin.config.Myconfig;
import com.qin.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,
// 通过配置类的class对象加载!
ApplicationContext context = new AnnotationConfigApplicationContext(Myconfig.class);
User user = (User) context.getBean("user");
System.out.println(user.getName());
}
}
总结:这种用java来接管的配置,在SpringBoot中随处可见!!!Spring完全可以摒弃XML的配置!!!
10、AOP(面向切面编程)
AOP的实现本质上利用的是代理模式(静态代理和动态代理)----代理的是接口
对应的程序为Spring-09-aop
再不改变原有的业务的情况下,添加新的功能(比如添加日志)!
10.1 什么是AOP
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现 程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的 一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使 得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
通俗的来讲:AOP就是在不改变原有逻辑的情况下,添加新的功能,如:日志、安全、缓存、事务等等!!!
10.2 AOP在Spring中的应用
-
横切关注点:通俗的讲就是,在不改变原有逻辑的情况下,执行添加新功能的点!
-
切面:自定义的一个类,后面还需要关注点和通知
-
通知:切面必须要完成的工作,通俗的讲就是类中的一个方法
-
-
Spring支持五种通知:
1、前置通知 2、后置通知 3、环绕通知 4、异常抛出通知 5、引介入通知
-
总结:AOP就是在不改变原有代码的情况下,去增加新的功能
10.3 使用Spring实现AOP
-
方式一:使用Spring的API接口实现
-
首先导入Maven的依赖
<!--使用AOP织入,需要导入一个依赖包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
-
然后再servlet的包下,定义UserService业务接口和UserServiceImpl实现类
- UserService的接口
package com.qin.service; public interface UserService { public void add(); public void delete(); public void update(); public void select(); }
package com.qin.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("查询了一个用户!"); } }
-
在log包下,定义我们的增强类,一个前置通知和一个后置通知
- Log类
package com.qin.log; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { @Override // method :表示要执行的目标对象的方法 // agrs :参数 // target :目标对象 public void before(Method method, Object[] agrs, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行"); } }
package com.qin.log; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; public class AfterLog implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了"+method.getName()+"方法,返回结果为:"+returnValue); } }
-
配置benas.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" 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="userService" class="com.qin.service.UserServiceImpl"></bean> <bean id="log" class="com.qin.log.Log"/> <bean id="afterlog" class="com.qin.log.AfterLog"/> <!-- 方式一:使用原生的Spring API接口--> <!-- 配置AOP:需要导入AOP的约束--> <aop:config> <!-- 切入点:就是我们的代码在哪执行--> <aop:pointcut id="pointcut" expression="execution(* com.qin.service.UserServiceImpl.*(..))"/> <!-- 执行环绕增加!!!--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/> </aop:config> </beans>
-
测试
- MyTest类
import com.qin.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 此处唯一一点的不同是:到那个太代理代理的是接口:这个是注意点 UserService userService = (UserService) context.getBean("userService"); userService.delete(); } // AOP 就是在不影响原来业务的情况下,实现动态增强 }
-
-
方式二:自定义的类来实现AOP【主要是切面定义】
-
创建DIYPointCut.class
package com.qin.diy; public class DiyPointCut { public void before(){ System.out.println("=======方法执行前========"); } public void after(){ System.out.println("=======方法执行后========"); } }
-
注册bean.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" 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="userService" class="com.qin.service.UserServiceImpl"></bean> <!-- 方式二:自定义类 相对来说比较简单,但是不如第一种使用--> <bean id="diy" class="com.qin.diy.DiyPointCut"/> <aop:config> <!-- 自定义切面,ref要引用的类--> <aop:aspect ref="diy"> <!--切入点--> <aop:pointcut id="point" expression="execution(* com.qin.service.UserServiceImpl.*(..))"/> <!--通知--> <aop:after method="after" pointcut-ref="point"/> <aop:before method="before" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
-
测试
-
-
方式三:注解实现AOP【注解实现还是有一定的约束和限制】
- 定义一个类【在类中,标注切面】
package com.qin.diy; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect //标注这是一个切面 public class AnnotationPointCut { // 前置通知 注解的内容主要是写切入点 @Before("execution(* com.qin.service.UserServiceImpl.*(..))") public void before(){ System.out.println("=====方法执行前======="); } // 后置通知 @After("execution(* com.qin.service.UserServiceImpl.*(..))") public void after(){ System.out.println("=====方法执行后======="); } // 环绕通知 @Around("execution(* com.qin.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前"); Object proceed = jp.proceed(); System.out.println("环绕后"); } }
- beans.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="userService" class="com.qin.service.UserServiceImpl"></bean> <!--第三种方式:使用注解来实现--> <bean id="annotationPointCut" class="com.qin.diy.AnnotationPointCut"/> <!--开启注解支持--> <aop:aspectj-autoproxy/>
10.4 总结
AOP主要学习的是一种横向编程的思想,即在不改变原有代码的情况下,实现业务的增强(本质上是使用的动态代理模式)!!!
11、整合Mybatis
11.1 回忆mybatis
步骤:
-
导入相应的jar包
- junit 测试工具包
- mybatis 包
- mysql-connector-java mysql的包
- Spring-webmvc的包
- aop的织入包
- mybatis-spring 整合包
- Spring-jdbc Spring操作数据库的包
- lombok 偷懒工具包
- 最后还需要配置资源过滤!!!
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>Spring-study</artifactId> <groupId>com.qin</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Spring-10-Mybatis</artifactId> <dependencies> <!--mysql的驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!--mybatis的依赖包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!--junit测试工具包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--偷懒工具lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> </dependency> <!--Spring的包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!--Spring操作数据库的话,需要这么一个包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!--使用AOP织入,需要导入一个依赖包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <!-- 整合mybatis和spring的包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> </dependencies> <!--资源过滤--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> </project>
-
Mybatis的步骤
- 导入jar包
- 编写xml配置文件
- 编写工具类
- 编写pojo实体类
- 编写接口
- 绑定接口
- 测试
11.2 Mybatis-Spring
配合联系的代码程序:Spring-10-Mybatis
-
整合方式一
首先需要导入需要的maven包 mybatis-spring
-
在Spring-dao.xml中:使用Spring的数据源替换Mybatis的数据源
<!-- 使用Spring的数据源替换Mybatis的配置 1、替换mybatis的数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://ip地址:3306/test_1?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="test_1"/> <property name="password" value="LAbrXKKXMsH3bwPn"/> </bean>
-
配置SqlSessionFactory,关联Mybatis
<!--配置SqlSessionFactory,关联Mybatis 第2步--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--关联mybatis的配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/> </bean>
-
注册sqlSessionTemplate,也就是我们需要的sqlsession
<!--注册注册sqlSessionTemplate,关联sqlSessionFactory--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
-
创建一个实现类(这就麻烦了!)(需要给接口加实现类,这是多了一步而已)
package com.qin.dao; import com.qin.pojo.User; import org.mybatis.spring.SqlSessionTemplate; import java.util.List; public class UserMapperImpl implements UserMapper{ private SqlSessionTemplate sqlSession; // Spring需要set方法的注入 public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } @Override public List<User> selectUser() { // 需要getmapper UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } }
-
注册bean.xml(将自己写的实现类,注册到Spring中)
<!-- 注册bean--> <bean id="userMapper" class="com.qin.dao.UserMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean>
-
测试
import com.qin.dao.UserMapper; import com.qin.pojo.User; import com.qin.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class MyTest { @Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper userMapper = context.getBean("userMapper",UserMapper.class); for (User user : userMapper.selectUser()) { System.out.println(user); } } }
-
总结思路:(不需要mybatis中的工具类了!!!)
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--核心配置文件 属性、配置、别名这三个务必掌握 --> <configuration> </configuration>
spring-dao.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" 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"> <!-- 使用Spring的数据源替换Mybatis的配置 1、替换mybatis的数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:/ip地址:3306/test_1?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="test_1"/> <property name="password" value="LAbrXKKXMsH3bwPn"/> </bean> <!--配置SqlSessionFactory,关联Mybatis 第2步--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--关联mybatis的配置文件 ,第三部--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/> </bean> <!--注册注册sqlSessionTemplate,关联sqlSessionFactory--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <!-- 第4步,需要接口的实现类--> <bean id="userMapper" class="com.qin.dao.UserMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean> </beans>
需要Spring的托管,所以需要实现类UserMapperImple.java
package com.qin.dao; import com.qin.pojo.User; import org.mybatis.spring.SqlSessionTemplate; import java.util.List; public class UserMapperImpl implements UserMapper{ private SqlSessionTemplate sqlSession; // Spring需要set方法的注入 public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } @Override public List<User> selectUser() { // 需要getmapper UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } }
-
-
整合方式二
SqlSessionDaoSupport
dao继承Support类 , 直接利用 getSqlSession() 获得 , 然后直接注入SqlSessionFactory . 比起方式1 , 不 需要管理SqlSessionTemplate , 而且对事务的支持更加友好 .
-
UserMapperImplTwo.java
package com.qin.dao; import com.qin.pojo.User; import org.mybatis.spring.support.SqlSessionDaoSupport; import java.util.List; public class UserMapperImplTwo extends SqlSessionDaoSupport implements UserMapper { @Override public List<User> selectUser() { return getSqlSession().getMapper(UserMapper.class).selectUser(); } }
-
Spring-dao.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" 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"> <!-- 使用Spring的数据源替换Mybatis的配置 1、替换mybatis的数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://ip地址:3306/test_1?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="test_1"/> <property name="password" value="LAbrXKKXMsH3bwPn"/> </bean> <!--配置SqlSessionFactory,关联Mybatis 第2步--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--关联mybatis的配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/> </bean> <!-- 第4步,需要接口的实现类--> <bean id="userMappertwo" class="com.qin.dao.UserMapperImplTwo"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>
-
mybatis-config,xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--核心配置文件 属性、配置、别名这三个务必掌握 --> <configuration> </configuration>
-
测试类
import com.qin.dao.UserMapper; import com.qin.pojo.User; import com.qin.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class MyTest { @Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper userMapper = context.getBean("userMappertwo",UserMapper.class); for (User user : userMapper.selectUser()) { System.out.println(user); } } }
12、声明式事务
12.1 回顾事务
- 把一组业务当成一个业务来做;要么都成功,要么都失败!
- 事务在项目的开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
- 确保完整性和一致性。
事务ACID原则:
- 原子性:
- 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用。
- 一致性:
- 一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中。
- 隔离性:(重点是防止数据的损坏!)
- 可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
- 持久性:
- 事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中。
引入程序Spring-11-transaction
- 导入jar包依赖
- 配置mybatis-config.xml
- 配置Spring-dao.xml操作
- 编写pojo的实体类
- dao中写接口
- 配置Mapper.xml
- 实现接口的类(目的是为了让Spring对类进行接管)
- 根据相应的需要配置Spring-dao(目的是为了实现AOP来管理事务)
-
Spring支持编程式事务和声明式事务管理
-
编程式事务
-
声明式事务
将事务管理的代码,从业务中分离出来,以声明的方式来管理事务**(其实是死的,谁需要配置事务,直接更改AOP的切入点即可)**
将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务 管理
-
-
导入相应的约束tx
<?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:tx="http://www.springframework.org/schema/tx" 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/tx https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 使用Spring的数据源替换Mybatis的配置 1、替换mybatis的数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://ip地址:3306/test_1?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="test_1"/> <property name="password" value="LAbrXKKXMsH3bwPn"/> </bean> <!--配置SqlSessionFactory,关联Mybatis 第2步--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--关联mybatis的配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/> </bean> <bean id="userMapperImpl" class="com.qin.dao.UserMapperImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> <!-- 开始Spring的事务管理(开启声明性事务)--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--结合AOP实现事务的织入 事务交给容器管理--> <!--配置事务的类:配置事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--给那些方法配置事务--> <!--配置事务的传播特性: new --> <tx:attributes> <tx:method name="add" propagation="REQUIRED"/> <tx:method name="delete" propagation="REQUIRED"/> <tx:method name="update" propagation="REQUIRED"/> <tx:method name="query" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!--配置AOP的操作--> <aop:config> <!--切入点pointcut--> <aop:pointcut id="txPointCut" expression="execution(* com.qin.dao.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
-
为什么要配置事务:事务在项目的开发过程中非常的重要,尤其是涉及到数据的一致性的问题,不容马虎!!!
13、Spring总结
- Spring重点是思想的学习 IOC和AOP
- 重点是7、8、9的使用
- 反射原理的学习!