Spring框架
1.简介
1.1 spring框架的能做什么?
Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
- 目的:解决企业应用开发的复杂性
- 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
- 范围:任何Java应用
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
1.2 spring框架的核心
- IOC 控制反转
- AOP 面向切面
2.IOC 控制反转
2.1 什么是控制反转
- 用白话来讲,就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。
- 这也就是所谓“控制反转”的概念所在:(依赖)控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
- IoC还有一个另外的名字:“依赖注入 (DI=Dependency Injection)” ,即由容器动态的将某种依赖关系注入到组件之中
2.2 ioc 具体如何实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aABrjopS-1590596858733)(E:\JAVA\java笔记\Java学习\image-20200524152122512.png)]
3. 第一个spring程序
1.导入maven依赖
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.zhao</groupId>
<artifactId>01-第一个spring程序</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--spring依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!--junit测试类依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!--lombok依赖 偷懒神器-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
</project>
- 创建需要被bean注册的实体类Person,Dog
package com.zhao.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {
private String name;
private int age;
}
package com.zhao.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private int age;
private Dog dog;
public void say(){
System.out.println("我的名字叫: " + name + ",年龄:" + age +
",还有一只可爱的小狗名字叫:" + dog.getName() + ",它" + dog.getAge() + "岁了.");
}
}
3.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用Spring来创建对象,bean来配置 -->
<!-- 构造器注入 -->
<!-- id: bean的唯一标识符,相当于对象名
class: 包名.类名
name: 别名,相当于bean的另外的标识符
constructor-arg name: 构造器的参数名
value: 参数的值
ref: 引用到哪个对象
-->
<bean class="com.zhao.pojo.Dog" id="dog" name="dog2">
<constructor-arg name="age" value="3"/>
<constructor-arg name="name" value="小黑"/>
</bean>
<bean id="person" class="com.zhao.pojo.Person" name="person2">
<constructor-arg name="age" value="11"/>
<constructor-arg name="name" value="小赵"/>
<constructor-arg name="dog" ref="dog"/>
</bean>
</beans>
<?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">
<import resource="bean.xml"/>
</beans>
- 编写测试类
import com.zhao.pojo.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01(){
// spring通过加载xml配置文件来控制
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 我们的对象都交由Spring来管理了,要使用就直接去调用就可以了 getBean
Person person = context.getBean("person2", Person.class);
person.say();
System.out.println(person.getDog());
}
}
4. 通过xml的几种注入方式
4.1 构造器注入
第一个程序已经演示过了
<!-- 构造器注入 -->
<!-- id: bean的唯一标识符,相当于对象名
class: 包名.类名
name: 别名,相当于bean的另外的标识符
constructor-arg name: 构造器的参数名
value: 参数的值
ref: 引用到哪个对象
-->
<bean class="com.zhao.pojo.Dog" id="dog" name="dog2">
<constructor-arg name="age" value="3"/>
<constructor-arg name="name" value="小黑"/>
</bean>
<bean id="person" class="com.zhao.pojo.Person" name="person2">
<constructor-arg name="age" value="11"/>
<constructor-arg name="name" value="小赵"/>
<constructor-arg name="dog" ref="dog"/>
</bean>
4.2 Set属性注入(相对重要)
xml配置:
<!-- Set属性注入-->
<bean class="com.zhao.pojo.Pc" id="pc">
<property name="name" value="小米笔记本"/>
<property name="year" value="3"/>
</bean>
<bean id="person1" class="com.zhao.pojo.Person">
<property name="name" value="小赵"/>
<!--bean-->
<property name="pc" ref="pc"/>
<!--数组-->
<property name="books">
<array>
<value>"红楼梦"</value>
<value>"三国演义"</value>
<value>"西游记"</value>
<value>"水浒传"</value>
</array>
</property>
<!--List-->
<property name="hobbys">
<list>
<value>听歌</value>
<value>敲代码</value>
<value>游戏</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="身份证" value="339005199108135116"/>
<entry key="银行卡" value="0061110008801661"/>
</map>
</property>
<!--set-->
<property name="games">
<set>
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
<!--null-->
<property name="wife" >
<null></null>
</property>
<!--properties-->
<property name="info">
<props>
<prop key="学号">20190108</prop>
<prop key="姓名">赵小赵</prop>
<prop key="性别">男</prop>
</props>
</property>
<property name="age" value="30"/>
<property name="boy" value="true"/>
</bean>
Person类:
package com.zhao.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
private String[] books;
private List<String> hobbys;
private Boolean boy;
private Object wife;
private Set<String> games;
private Map<String,Object> card;
// private Date birth;
private Pc pc;
private Properties info;
}
Pc类
package com.zhao.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Pc {
private String name;
private int year;
}
4.3 p命名空间.c命名空间注入
<?xml version="1.0" encoding="UTF-8"?>
<!--p命名空间,c命名空间注入需要单独再设置约束
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
-->
<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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--扩展注入-->
<!--p命名空间注入,可以通过p(属性)来注入值-->
<bean class="com.zhao.pojo.User" p:name="小赵" p:age="30" id="user1"/>
<!--c命名空间注入,可以通过c(构造器)来注入值-->
<bean class="com.zhao.pojo.User" c:name="赵玟兮" c:age="1" id="user2"/>
</beans>
4.4 byName和byType自动装配
实体类
package com.zhao.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Cat {
public void say(){
System.out.println("喵-----");
}
}
package com.zhao.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Dog {
public void say(){
System.out.println("汪-----");
}
}
package com.zhao.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person01 {
private String name;
private Dog dog;
private Cat cat;
}
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 class="com.zhao.pojo.Cat" id="cat"/>
<bean class="com.zhao.pojo.Dog" id="dog"/>
<!--byName:根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。-->
<bean class="com.zhao.pojo.Person01" id="person01" autowire="byName">
<property name="name" value="肖玉清"/>
</bean>
<!--byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;
如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,
则什么事都不发生,也可以通过设置 -->
<bean class="com.zhao.pojo.Person01" id="person02" autowire="byType">
<property name="name" value="肖玉清"/>
</bean>
</beans>
5. 通过注解实现注入
- 需要xml导入依赖
- 需要xml开启注解支持context:annotation-config/
5.1 @Autowired注解与@resource注解
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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解支持-->
<context:annotation-config/>
<bean id="dog1" class="com.zhao.pojo.Dog"/>
<bean id="dog2" class="com.zhao.pojo.Dog"/>
<bean id="cat1" class="com.zhao.pojo.Cat"/>
<bean id="cat2" class="com.zhao.pojo.Cat"/>
<bean id="user" class="com.zhao.pojo.User"/>
</beans>
实体类:
package com.zhao.pojo;
import lombok.Data;
@Data
public class Cat {
public void show(){
System.out.println("喵----");
}
}
package com.zhao.pojo;
public class Dog {
private String name;
private int age;
}
package com.zhao.pojo;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.Resource;
@Data
public class User {
/**@Autowired(required=false) 允许字段为null
*
*/
@Autowired(required=false)
private String name;
/** @Autowired 注解自动装配 Autowired需要在xml中开启 <context:annotation-config/>
@Qualifier(value = "xxx") 当命名和类型不一致的时候需要用Qualifier来指定
*/
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
@Autowired
@Qualifier(value = "cat1")
private Cat cat;
// @Resource(name = "dog1")
// private Dog dog;
// @Resource(name = "cat2")
// private Cat cat;
}
5.1 @Autowired注解与@resource注解的区别
- 作用基本相同,都能达到自动装配(相当于自动寻找本字段相对应类属性的,已注册的bean),与xml中ref相当
@Autowired为Spring提供的注解,默认按照ByType类型注入
- @Resource注解由J2EE提供,默认按照ByName自动注入
- @Autowired注解由spring提供,默认按照ByType自动注入
- @Autowired(required=false) 允许字段为null
- @Autowired 与@Qualifier(value = “xxx”) 搭配可以直接指定属性与本字段一致的bean
5.2 @Component及其他
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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解支持-->
<context:annotation-config/>
<!--注解扫描-->
<context:component-scan base-package="com.zhao"/>
</beans>
实体类:
package com.zhao.dao;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class Cat {
@Value("小黑")
private String name;
@Value("2")
private int age;
}
package com.zhao.dao;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class Dog {
@Value("十七")
private String name;
@Value("22")
private int age;
}
package com.zhao.dao;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class User {
@Value("小赵")
private String name;
@Autowired
private Dog dog;
@Autowired
private Cat cat;
}
@component的作用详细介绍
1、@Service用于标注业务层组件
2、@Controller用于标注控制层组件(如struts中的action)
3、@Repository用于标注数据访问组件,即DAO组件.
4、@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Value(“xxx”):给该字段赋值为xxx
6.javaconfig来配置
java配置类
package com.zhao.config;
import com.zhao.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**@Configuration :加上这个表示Java配置类文件 相当于 xml配置文件
* @Bean : 表示这个注册成一个bean 相当于<bean id="getUser" class="com.zhao.dao.User"/>
*/
@Configuration
public class Myconfig {
@Bean
public User getUser(){
return new User();
}
}
User实体类
package com.zhao.pojo;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
@Data
public class User {
@Value("小赵")
private String name;
}
import com.zhao.config.Myconfig;
import com.zhao.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
@Test
public void test01(){
// 通过加载java配置类来获得class加载对象
ApplicationContext context = new AnnotationConfigApplicationContext(Myconfig.class);
// 加载bean文件
User getUser = context.getBean("getUser", User.class);
System.out.println(getUser.getName());
}
}
7.AOP 面向切面编程
7.1 代理模式
- 静态代理
- 动态代理
7.1.1 静态代理
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.
接口:
package com.zhao.pojo;
/**
* 接口
*/
public interface IUserDao {
public void save();
}
实体类:
package com.zhao.pojo;
/**
* 继承接口,重写方法
*/
public class UserDao implements IUserDao{
public void save() {
System.out.println("------已保存数据");
}
}
代理类:
package com.zhao.pojo;
/**代理对象,静态代理
* 代理类相当于实现了2次接口,一次直接通过继承的接口,另外一次通过实例化一个接口的继承类
* 实例化的接口继承类用来实现接口本身的方法
* 直接继承的接口,通过重写来实现功能增加
*/
public class UserDaoProxy implements IUserDao {
// 接收保存目标对象
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target = target;
}
public void save() {
System.out.println("开始事务");
target.save();
System.out.println("提交事务");
}
}
test类:
package com.zhao.pojo;
public class Mytest {
public static void main(String[] args) {
UserDao userDao = new UserDao();
UserDaoProxy userDaoProxy = new UserDaoProxy(userDao);
userDaoProxy.save();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KmziHuxJ-1590596858735)(E:\JAVA\java笔记\Java学习\image-20200526215402857.png)]
静态代理总结:
1.可以做到在不修改目标对象的功能前提下,对目标功能扩展.
2.缺点:
- 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.
7.1.2 动态代理
- 基于接口 --jdk动态代理
- 基于类 – cglib
- java字节码实现: javasist
7.2 AOP的实现
- 第一步:需要导入aop依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
- 第二步:xml中要导入aop约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns: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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
定义一个接口
package com.zhao.service;
public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}
接口的实现类
package com.zhao.service;
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("增加一个用户");
}
public void delete() {
System.out.println("删除一个用户");
}
public void update() {
System.out.println("修改一个用户");
}
public void select() {
System.out.println("查询一个用户");
}
}
测试类
import com.zhao.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationController.xml");
// 动态代理代理的是接口,这边需要写接口
UserService userService = context.getBean("userService", UserService.class);
userService.add();
userService.delete();
userService.select();
userService.update();
}
}
7.2.1 使用spring的api接口(最复杂,适用于面试)
设置两个log类
package com.zhao.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class log implements MethodBeforeAdvice {
/**
*
* @param method 要执行的对象方法
* @param objects 参数
* @param o 目标对象
* @throws Throwable
*/
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName() + "的"+method.getName() + "被执行了");
}
}
package com.zhao.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
*/
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("执行了" + method.getName() + "的方法,返回值是:" + o);
}
}
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
http://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="afterLog" class="com.zhao.log.AfterLog"/>
<bean id="log" class="com.zhao.log.log"/>
<bean id="userService" class="com.zhao.service.UserServiceImpl"/>
<!-- 配置aop:需要导入对应的aop约束-->
<!--方式一:使用spring的api接口-->
<aop:config>
<!--切入点-->
<aop:pointcut id="poi" expression="execution(* com.zhao.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加-->
<aop:advisor advice-ref="log" pointcut-ref="poi"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="poi"/>
</aop:config>
</beans>
7.2.2 使用div切面(相对简单)
自定义一个切面的类
package com.zhao.log;
public class diyLog {
public void before1(){
System.out.println("-----------方法执行前-------------");
}
public void after1(){
System.out.println("----------方法执行后------------");
}
}
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
http://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.zhao.service.UserServiceImpl"/>
<!-- 配置aop:需要导入对应的aop约束-->
<!--方式二:自定义类来切面-->
<bean id="diyLog" class="com.zhao.log.diyLog"/>
<aop:config>
<!--自定义切面,ref引用到div的类-->
<aop:aspect ref="diyLog">
<!--设置切入点-->
<aop:pointcut id="divpio" expression="execution(* com.zhao.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before1" pointcut-ref="divpio"/>
<aop:after method="after1" pointcut-ref="divpio"/>
</aop:aspect>
</aop:config>
</beans>
7.2.3 使用注解(最简单)
自定义一个切面功能增强的类
package com.zhao.log;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @author hanbaobao
* @Aspect 标注这是一个切面
* @Before 在切入点前执行
* @After 在切入点后执行
* "execution(* com.zhao.service.UserServiceImpl.*(..))" execution(所有的类中 包名...类名.方法(参数))
*/
@Aspect
public class AnPoint {
@Before("execution(* com.zhao.service.UserServiceImpl.*(..))")
public void before1() {
System.out.println("-----------方法执行前-----------");
}
@After("execution(* com.zhao.service.UserServiceImpl.*(..))")
public void after1() {
System.out.println("-----------方法执行后-----------");
}
}
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
http://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.zhao.service.UserServiceImpl"/>
<!--方式三:通过注解来实现-->
<bean id="anPoint" class="com.zhao.log.AnPoint"/>
<!--aop自动切面支持开启-->
<aop:aspectj-autoproxy/>
</beans>
8.整合mybatis
9.事务管理
- 编程式事务
- 声明式事务(一般用这个)
声明式事务步骤
- 导入xml事务约束
- 配置声明式事务,并通过aop切面来配置事务
<?xml version="1.0" encoding="UTF-8"?>
<!--需要导入 约束-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--结合aop实现事务的织入-->
<!--配置事务的类-->
<tx:advice id="interceptor" transaction-manager="transactionManager">
<!--给哪些方法配置事务 propagation="REQUIRED"默认这个,开启事务-->
<tx:attributes>
<tx:method name="selectStudent" propagation="REQUIRED"/>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="t" expression="execution(* com.zhao.mapper.*.*(..))"/>
<aop:advisor advice-ref="interceptor" pointcut-ref="t"/>
</aop:config>
/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--结合aop实现事务的织入-->
<!--配置事务的类-->
<tx:advice id="interceptor" transaction-manager="transactionManager">
<!--给哪些方法配置事务 propagation="REQUIRED"默认这个,开启事务-->
<tx:attributes>
<tx:method name="selectStudent" propagation="REQUIRED"/>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="t" expression="execution(* com.zhao.mapper.*.*(..))"/>
<aop:advisor advice-ref="interceptor" pointcut-ref="t"/>
</aop:config>