狂神Spring教学笔记+源码
1、Spring
所有代码已上传gitee
https://gitee.com/deza-to/learn-spring
1.1、简介
-
Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架。
-
SSH : Struct2+Spring+Hibernate
-
SSM : SpringMVC+Spring+Mybatis
官网:https://spring.io/projects/spring-framework
官方下载地址:https://repo.spring.io/release/org/springframework/spring/
<!-- 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>
1.2、优点
- Spring是一个开源的免费的框架(容器)
- Spring是一个轻量级的,非入侵式的框架
- 控制反转(IOC),面向切面编程(AOP)
- 支持事务处理,对框架整合的支持
总结一句话:Spring就是一个轻量级的控制反转和面向切面编程的框架
1.3、组成

1.4、拓展
- Spring Boot
- 一个快速开发的脚手架
- 基于SpringBoot可以快速的开发单个微服务
- 约定大于配置
- Spring Cloud
- SpringCloud是基于SpringBoot实现的
因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC。
Spring弊端:发展了太久之后,违背了原来的理念。配置十分繁琐,人称“配置地域”。
2、IOC理论推导
- UserDao接口
- UserDaoImpl实现类
- UserService业务接口
- UserServiceImpl业务实现
-
创建Maven项目
<groupId>com.chen</groupId> <artifactId>spring-study</artifactId> <version>1.0-SNAPSHOT</version> -
导入依赖
<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> </dependencies>
在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改源代码。如果程序代码量十分大,修改一次的成本代价十分昂贵。
我们使用一个Set接口实现
private UserDao userDao;
//利用set进行动态实现值得注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
- 之前,程序是主动创建对象,控制权在程序员手上。
- 使用了set注入之后,程序不再具有主动性,而是变成了被动的接受对象。
这种思想从根本上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注在业务实现上。这是IOC的原型。
IOC本质
控制反转Ioc(inversion of control),是一种设计思想,DI(依赖注入)是实现Ioc的一种方法,也有人认为DI只是Ioc的另一种说法。没有Ioc的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是获得依赖对象的方式反转了。
采用Xml方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解方式可以把二者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是Ioc容器,其实现方法是依赖注入(Dependency Injection,DI)
3、Hello Spring
在resources目录下创建一个xml文件来配置Bean,文件名可以任意,默认是ApplicationContext.xml
文件内容的模板(xml文件头),可以从Spring的官网获取:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core
<?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。class不需要带.java-->
<bean id="hello" class="com.chen.pojo.Hello">
<property name="name" value="Spring"/>
<!-- collaborators and configuration for this bean go here -->
</bean>
</beans>
id:要创建的对象名
class:类型
property:注入属性
测试类获取Spring容器中的对象,并调用其方法:
import com.chen.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
//我们的对象现在都在Spring中管理了,我们要使用,直接去里面取来就可以
Hello hello = (Hello) context.getBean("hello");
hello.show();
}
}
思考问题
-
Hello对象是谁创建的?
Spring创建的
-
Hello对象的属性是怎么设置的
是由Spring容器设置的
这个过程就叫控制反转
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring之后,对象是由Spring来创建的。
反转:程序本身不创建对象,而变成被动的接收对象。
依赖注入:就是利用set方法来进行注入的。
IOC是一种编程思想,由主动的编程变成被动的接收。
可以通过new ClassPathXmlApplicationContext去浏览一下底层源码
OK,到了现在,我们彻底不用再去程序中改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配。
4、IOC创建对象的方式
-
使用无参构造函数 创建对象,默认。
-
假设我们要使用有参构造创建对象。
-
下标赋值
<!--第一种方式,下标赋值--> <bean id="user" class="com.chen.pojo.User"> <constructor-arg index="0" value="peng"/> </bean> -
类型
<!--第二种方式,通过类型创建,不建议使用--> <bean id="user" class="com.chen.pojo.User"> <constructor-arg type="java.lang.String" value="旭宝"/> </bean> -
参数名
<!--第三种方式,参数名,推荐使用--> <bean id="user" class="com.chen.pojo.User"> <constructor-arg name="name" value="Spring"/> </bean>
-
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了。
5、Spring配置
5.1、别名
<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="newUser"/>
5.2、Bean的配置
<!--
id:bean的唯一标识符,也就是相当于对象名
class:bean对象所对应的全限定名:包名+类名
name:也是别名,而且name可以同时取多个别名
-->
<bean id="user" class="com.chen.pojo.User" name="user1,user2,user3">
<constructor-arg name="name" value="Spring"/>
</bean>
5.3、import
一般用于团队开发使用,也可以将多个配置文件导入合并为一个
假设,现在项目中有多个人开发,这三个人负责不同的模块,import将每个人各自编写的配置Bean的xml文件整合在一起。
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
6、依赖注入【DI】
6.1、构造器注入
参考前文
6.2、Set方式注入【重点】
- 依赖注入:Set注入
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
【环境搭建】
-
复杂类型
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } -
真实测试对象
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; } -
applicationContext.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.chen.pojo.Address"/> <bean id="student" class="com.chen.pojo.Student"> <!--第一种,普通值注入,value--> <property name="name" value="chen"/> <!--第二种,Bean注入,ref--> <property name="address" ref="address"/> <!--数组注入,ref--> <property name="books"> <array> <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="123456123456"/> <entry key="身份证" value="1111111111122223333"/> </map> </property> <!--Set--> <property name="games"> <set> <value>王者荣耀</value> <value>和平精英</value> </set> </property> <!--null--> <property name="wife"> <null/> </property> <!--properties--> <property name="info"> <props> <prop key="学号">99021154</prop> <prop key="性别">男</prop> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans> -
测试类
import com.chen.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("applicationContext.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); } }
6.3、扩展方式注入
可以使用p命名空间和c命名空间进行注入
<?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.chen.pojo.User" p:name="chen" p:age="18"/>
<!--c命名空间注入,通过构造器注入:constructor-args-->
<bean id="user2" class="com.chen.pojo.User" c:age="16" c:name="奥特曼"/>
</beans>
测试
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("user.xml");
User user = context.getBean("user2",User.class);
System.out.println( user);
}
注意点:p命名空间和c命名空间不能直接使用,需要导入xml约束
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
6.4、bean的作用域

-
单例模式(Spring默认)
<bean id="user" class="com.chen.pojo.User" p:name="chen" p:age="18" scope="singleton"/> -
原型模式:每次从容器中get一个新对象
<bean id="user2" class="com.chen.pojo.User" c:age="16" c:name="奥特曼" scope="prototype"/> -
其余的request、session、application只能在web开发中使用到。
7、Bean的自动装配
- 自动装配是Spring满足bean依赖的一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有三种装配方式
- 在xml中显示配置
- 在java中显示配置
- 隐式的自动装配bean【重要】
7.1、ByName自动装配
<bean id="cat" class="com.chen.pojo.Cat"/>
<bean id="dog" class="com.chen.pojo.Dog"/>
<!--byName:会在容器上下文中查找,和自己对象set方法后面的值对应的beanid-->
<bean id="people" class="com.chen.pojo.People" autowire="byName">
<property name="name" value="旭旭"/>
</bean>
7.2、ByType自动装配
<bean class="com.chen.pojo.Cat"/>
<bean class="com.chen.pojo.Dog"/>
<!--byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean-->
<bean id="people" class="com.chen.pojo.People" autowire="byType">
<property name="name" value="鹏鹏"/>
</bean>
小结:
- byName的时候,需要保证所有bean的id唯一,并且这个bean的id需要和自动注入的属性的set方法的值一致。
- byType的时候,需要保证所有bean的class唯一,并且这个bean的class需要和自动注入的属性的类型一致。
7.3、使用注解实现自动装配
jdk1.5支持注解,Spring2.5开始支持注解。
在实际工作中使用注解的情况更多。
要使用注解须知:
-
导入约束:context约束(xmlns:context="http://www.springframework.org/schema/context")
-
配置文件开启注解的支持context:annotation-config/
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-i nstance" 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>
@Autowire
直接在属性上使用即可,也可以在set方法上使用
使用Autowired可以不用编写set方法了,前提是这个自动装配的属性在IOC(Spring)容器中存在(在applicationContext.xml文件中存在)。
@Autowired默认按类型装配(byType)(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配(byName)可以结合@Qualifier注解进行使用,如下:
@Autowired @Qualifier("window2") private Window window;
@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
@Resource private Door door;
@Resource和@Autowired异同
- 都是用来自动装配的,都可以放在属性字段上
- @Autowired默认通过byType的方式实现,且这个bean必须在xml中被配置
- @Resource默认通过byName的方式实现,如果找不到名字则通过byType实现,如果两个都找不到的情况下才报错
- 执行顺序不同:@Autowired默认通过byType,@Resource默认通过byName
8、使用注解开发
在Spring4之后,要使用注解开发,必须保证aop的包导入了

使用注解需要导入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>
1、bean
2、属性如何注入
//等价于<bean id="user" class="com.chen.pojo.User"/>
//@Component 组件
@Component
public class User {
//相当于<property name="name" value="旭旭"/>
@Value("旭旭")
public String name;
}
3、衍生注解
@Component有几个衍生注解,我们在web开发中会按照mvc三层架构分层。这四个注解作用是一样的。
- Dao【@Repository】
- Service【@Service】
- Controller【@Controller】
4、自动装配
@Autowired
@Resource
@Nullable 字段标记了这个注解,说明这个字段可以为null
5、作用域
//单例
@Scope("singleton")
public class User
//多实例
@Scope("prototype")
public class User
6、小结
xml与注解:
- xml更加万能,适用于任何场合,维护简单方便
- 注解:不是自己的类使用不了,维护相对复杂
最佳实践:
- xml用来管理bean
- 注解只负责完成属性的注入
- 在使用的过程中需要注意必须让注解生效,需要开启注解的支持
<!--开启注解的支持-->
<context:annotation-config/>
<!--开启包扫描,指定的包下面的注解就会生效-->
<context:component-scan base-package="com.chen"/>
9、使用java的方式配置Spring
用java类完全替代Spring的xml配置。
JavaConfig是Spring的一个子项目,在Sping4之后它成为一个核心功能。
package com.chen.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//这个注解的意思,说明这个类被Spring接管了,即注册到了容器中
@Component
public class User {
private int id;
public int getId() {
return id;
}
//属性注入值
@Value("12")
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
'}';
}
}
package com.chen.config;
import com.chen.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
//这个类也会被Spring容器托管,注册到容器中,因为他本身就是被@Component修饰,
// @Configuration代表这是一个配置类,就和applicationContext.xml是一样的
@Configuration
@ComponentScan("com.chen.pojo")//默认不写也是可以扫描的
@Import(MyConfig2.class)//将另一个配置类引入
public class MyConfig {
//注册一个bean,相当于一个bean标签
//方法名相当于bean标签中的id属性
//返回值类型相当于bean标签中的class属性
@Bean
public User getUser(){
//返回要注入到bean的对象
return new User();
}
}
import com.chen.config.MyConfig;
import com.chen.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
@Test
public void test1(){
//如果完全使用了配置类去做,那就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User) context.getBean("getUser");
System.out.println(user.getId());
}
}
这种纯java的配置方式,在SpringBoot中随处可见。
10、代理模式
为什么要学习代理模式?因为这是SpringAOP的底层。【SpringAOP和SpringMVC】
代理模式的分类:
- 静态代理
- 动态代理

10.1、静态代理
角色分析:
- 抽象角色:一般会用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作
- 客户:访问代理对象的人
代码步骤:
-
接口
public interface Rent { public void rent(); } -
真实角色
//房东 public class Host implements Rent{ public void rent(){ System.out.println("房东要出租房子"); } } -
代理角色
public class Proxy { private Host host; public Proxy(Host host) { this.host = host; } public Proxy() { } public void rent(){ seeHouse(); host.rent(); sign(); fare() ; } public void seeHouse(){ System.out.println("中介带看房"); } public void sign(){ System.out.println("签租租赁合同"); } public void fare(){ System.out.println("收中介费"); } } -
客户端访问代理角色
public class Client { public static void main(String[] args) { Host host = new Host(); //代理,中介帮房东租房子,但是中介一般要做一些附加的事 Proxy proxy = new Proxy(host); proxy.rent(); } }
代理模式的好处:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
- 公共业务交给代理类去做,实现了业务的分工。
- 公共业务发生扩展时,方便集中管理。
缺点:
- 一个真实角色就会产生一个代理角色;代码量会翻倍。开发效率会变低。
10.2、加深理解
聊聊AOP

10.3、动态代理
- 动态代理和静态代理角色一样(抽象角色,真实角色,代理角色)
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:基于接口的动态代理、基于类的动态代理
- 基于接口---JDK动态代理
- 基于类:cglib
- java字节码:javassist
需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序
动态代理的好处:
- 动态代理和静态代理角色一样(抽象角色,真实角色,代理角色)
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:基于接口的动态代理、基于类的动态代理
- 一个动态代理类代理的是一个接口,一般就是对应一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可
11、AOP
11.1、什么是AOP
【重点】使用AOP织入,需要导入一个依赖包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
配置类中加入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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
方式一:使用Spring的API接口【主要SpringAPI接口实现】
- 增强的功能想要实现SpringAPI接口(通知)
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice {
//method:要执行的目标对象的方法
//args:参数
//target:目标对象
public void before(Method method, Object[] objects, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"被调用了");
}
}
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了"+method.getName()+"方法,返回结果为"+returnValue);
}
}
- 切入点(实现一个接口)
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}
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 query() {
System.out.println("查询了一个用户");
}
}
- 配置文件
<!--注册bean-->
<bean id="userService" class="com.chen.service.UserServiceImpl"/>
<bean id="log" class="com.chen.log.Log"/>
<bean id="afterLog" class="com.chen.log.AfterLog"/>
<!--方式一:使用SpringAPI原生的接口,功能强大,可以对切入点方法做更多的事情-->
<!--配置aop需要导入aop的约束-->
<aop:config>
<!--切入点,expression表达式,execution(要执行的位置!)-->
<aop:pointcut id="pointcut" expression="execution(* com.chen.service.UserServiceImpl.*(..))"/>
<!--执行环绕增强-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
- 测试
import com.chen.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.add();
}
}
方式二:自定义来实现AOP【主要是切面定义】
- 自定义一个切面类
public class DiyPointCut {
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}
- 切入点和方法一一样
- 配置
<bean id="diy" class="com.chen.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面,ref要引用的类-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.chen.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
方式三:使用注解实现
-
开启注解支持
<!--开启注解支持--> <aop:aspectj-autoproxy/> -
用注解修饰类和方法
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; 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.chen.service.UserServiceImpl.*(..))") public void before(){ System.out.println("------方法执行前------"); } @After("execution(* com.chen.service.UserServiceImpl.*(..))") public void after(){ System.out.println("------方法执行后------"); } @Around("execution(* com.chen.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint pj) throws Throwable { System.out.println("------环绕前------"); //获得签名 Signature signature = pj.getSignature(); System.out.println("Signature"+signature); //执行方法 Object proceed = pj.proceed(); System.out.println("------环绕后------"); } } -
配置
<!--方式三:使用注解-->
<bean id="annotationPointCut" class="com.chen.diy.AnnotationPointCut"/>
12、整合Mybatis
步骤
-
导入相关jar包
- junit
- mybatis
- mysql数据库
- spring相关的
- aop织入
- mybatis-spring
<?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.chen</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-10-mybatis</artifactId> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!--Spring操作数据库需要一个spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> </dependencies> </project> -
编写配置文件
-
测试

浙公网安备 33010602011771号