Spring开源框架
(一)Spring简介
1.轻量化开源框架
2.解决企业应用开发的复杂性,降低难度
3.Spring的两个核心部分:IOC 和 Aop
1. IOC:控制反转
把创建对象的过程交给spring管理
2. Aop:面向切面
不修改源代码进行功能增强
3.Spring特点
(1)方便解耦,简化开发
(2)Aop编程支持
(3)方便程序的测试
(4)方便和其他框架整合
(5)方便进行事务操作
(6)降低API开发难度
(二)入门小案例
1.下载Spring资源文件
最新5.29大概80多mb,链接:
选 spring-5.2.9.RELEASE-dist.zip 这个文件,下载比较慢的话可以复制链接用迅雷下载,下载好解压:
2.选取需要的jar包
小案例需要四个基础的jar包
都可以在解压好的libs中找到,commons-logging需要自行下载
3.打开IDEA创建Java 项目
打开idea创建普通的项目,将上面5个jar包导入到项目并添加环境变量
创建一个简单的User类:
package com.bgu.edu;
public class User {
public void add(){
System.out.println("add-------");
}
}
在src目录下,创建spring配置文件,new ---------> XML Configuration File -------> Spring config 起个名字叫bean1
<?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">
<!--配置User对象-->
<bean id="user" class="com.bgu.edu.User"></bean>
</beans>
添加标签,按照图示 设置id和class的地址
4.创建测试类
新建pakage:test 在包内创建测试类TestSpring.class
package test;
import com.bgu.edu.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TeatSpring {
@Test
public void testAdd(){
//加载Spring配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("bean1.xml");
User user = context.getBean("user", User.class);
//运行User的构造方法
System.out.println(user);
user.add();
}
}
这里使用@Test会报错,点右面感叹号选第一个推荐方式,会自动导入:org.junit.Test 这个包,右键运行即可:
运行结果:
com.bgu.edu.User@27808f31
add-------
Process finished with exit code 0
(三)IOC
0.IOC 概念和原理
-
什么是IOC:控制反转,最常见的方式叫依赖注入。把创建对象和对象之间的调用过程交给Spring进行管理
-
使用IOC的目的:为了耦合度降低
-
做入门案例就是IOC实现
1.IOC 底层原理
-
xml解析技术、工厂模式、反射
class UserFactory { public static UserDao getDao(){ String classVlaue = class属性值;//1.xml解析得到class Class clazz = Class.forName(classValue);//2.通过反射创建对象 return (UserDao) clazz.newInstance(); } }
2.IOC 接口(BeanFactory)
-
IOC 思想基于 IOC容器底层就是对象工厂
-
Spring 提供了IOC容器的实现方式(两个接口)
(1)BeanFactory:IOC容器基本实现,是Spring内部使用的接口,不提供开发人员使用
特点:加载配置文件时不会创建对象,在获取对象(使用)才会创建对象 User user = context.getBean(“user”,User.class)
(2)ApplicationContext:BeanFactory的子接口,提供更多更强大的接口。一般由开发人员使用
特点:加载配置文件的时候就会把配置文件里的对象进行创建
3.IOC 操作Bean管理
-
什么是Bean 管理
(0)Bean管理是指两个操作
(1)Spring 创建对象
(2)Spring 注入属性
4.IOC 操作Bean管理(基于xml)
-
<bean id="user" class="com.bgu.edu.User"></bean>
在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
(1)bean 标签里有很多属性
- id属性:唯一标识
- class属性:类全路径(包类路径)
- name属性:与id类似,name可以使用特殊字符,早期为strues1提供
(2)创建对象时,默认执行无参构造方法
-
基于xml方式注入属性
-
DI:依赖注入,就是注入属性
第一种方式:使用set方法进行中注入
首先,创建一个对象
package com.bgu.edu; /** * 演示使用set方法注入属性 */ public class Book { //创建基本属性 private String bname; private String bauthor; //创建属性对象的set方法 public void setBname(String bname) { this.bname = bname; } public void setBauthor(String bauthor) { this.bauthor = bauthor; } }
然后配置spring文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--配置Book对象--> <bean id="book" class="com.bgu.edu.Book"> <!--使用property完成属性注入 name:类里的属性名称 value:向属性注入的值 --> <property name="bname" value="已经近"></property> <property name="bauthor" value="哈哈哈"></property> </bean> </beans>
第二种方式:有参构造方法进行注入
首先,创建一个对象
package com.bgu.edu; /** * 使用有参数方法构造注入 */ public class Orders { //属性 private String oname; private String address; //有参构造方法 public Orders(String oname, String address) { this.oname = oname; this.address = address; } @Override public String toString() { return "Orders{" + "oname='" + oname + '\'' + ", address='" + address + '\'' + '}'; } }
然后配置spring文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="orders" class="com.bgu.edu.Orders"> <constructor-arg name="oname" value="电脑"/> <constructor-arg name="address" value="中国"/> </bean> </beans>
spring配置简化:使用p名称空间注入
xmlns:p = "http://www.springframework.org/schema/p"
<bean id="orders" class="com.bgu.edu.Orders" p:bname="高等数学" p:bauthor="高同学"> </bean>
-
5.IOC 操作Bean管理(基于注入其他属性)
-
字面量
- null值
<property name="bname" > <null/> </property>
- 属性值包含特殊夫符号(转义 < >)
<property name="bname" > <value> <![CDATA[这里写带特殊的字符]]> </value> </property>
2.注入属性 - 外部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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- service和到对象的创建--> <bean id="userService" class="server.UserService"> <!--注入userDao对象 name属性,类里面属性名称 ref属性:创建userDao对象bean标签的id值 --> <property name="userDao" ref="userDaoImpl"></property> </bean> <!-- 注意 UserDao是接口,这里要写接口的实现类 也就是UserDaoImpl --> <bean id="userDaoImpl" class="dao.UserDaoImpl"></bean> </beans>
3.注入属性 - 内部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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--内部 Bean--> <bean id="emp" class="bean.Emp"> <property name="ename" value="李逵"></property> <property name="gender" value=" 男"></property> <property name="dept" > <bean id="dept" class="bean.Dept"> <property name="dname" value="行政部"></property> </bean> </property> </bean> </beans>
6.IOC 操作Bean管理(xml注入集合属性)
-
注入数组类型属性
-
注入List集合类型属性
-
注入Map集合类型属性
<?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 name="stu" class="edu.Stu"> <property name="courses"> <array> <value>java</value> <value>数据库</value> </array> </property> <property name="list" > <list> <value>张三</value> <value>小三</value> </list> </property> <property name="maps" > <map> <entry key="JAVA" value="java"/> <entry key="PHP" value="php"/> </map> </property> <property name="sets" > <set> <value>MySQL</value> <value>Redis</value> </set> </property> </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"> <bean name="stu" class="edu.Stu"> <property name="courseList"> <list> <ref bean="course1"></ref> <ref bean="course2"></ref> </list> </property> </bean> <bean id="course1" class="edu.Course"> <property name="cname" value="Spring 5"></property> </bean> <bean id="course2" class="edu.Course"> <property name="cname" value="MyBites"></property> </bean> </beans>
-
把集合注入提取到公共部分
-
在spring配置文件添加命名空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util = "http://www.springframework.org/schema/util" 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 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <util:list id="booklist"> <value>已经经</value> <value>是大家还是</value> <value>以哦他</value> </util:list> <bean id="book" class="edu.Book"> <property name="list" ref="booklist"></property> </bean> </beans>
-
7.IOC 操作 Bean 管理(FactoryBean)
- Spring 有两种 bean ,一种普通bean,一种factorybean
- 普通bean:在配置文件中定义的bean类型就是返回类型
- 工厂bean:在配置文件中定义的bean类型可以不是返回的bean类型
8.IOC 操作 Bean 管理(bean作用域)
- 在spring里面,设置创建bean实例是单实例还是多实例
- 在spring里面,默认情况下是单实例对象
- 如何设置单实例还是多实例:scope
- scope是属性值:singleton(单实例)、prototype(多实例)
- singleton(单实例):加载spring时,就会创建多实例对象
- prototype(多实例):不是在加载spring创建对象,在调用getBean时才会创建的对象
9.IOC 操作 Bean 管理(bean 生命周期)
- 生命周期:从对象创建和销毁的过程
- bean生命周期:
- 通过构造器创建Bean实例(无参构造方法)
- 为bean的属性设置属性值和对其他bean引用(调用set方法)
- 调用bean的初始化方法(需要进行配置初始化的方法)
- bean可以使用了
- 当容器关闭时,调用bean的销毁方法(需要进行配置销毁方法)
10.IOC 操作 Bean 管理(xml自动装配)
-
什么是自动装配
-
根据指定装配规则(属性名称或属性类型),Spring自动将匹配的属性值填入
- 实现方式:bean标签属性:autowire,配置自动装配 autowire有两个属性:byName 根据属性名注入,注入值bean的id值和类属性名称一样 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--自动装配--> <bean id="emp" class="autowire.Emp" autowire="byName"></bean> <bean id="dept" class="autowire.Dept"></bean> </beans>
-
11.IOC 操作 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/userdb"></property> <property name="username" value="root"></property> <property name="password" value=""></property> </bean> </beans>
-
-
引入外部属性文件配置数据库连接池
- 创建外部属性文件,properties格式文件,写数据库信息
prop.driverClassName = com.mysql.jdbc.Driver prop.url = jdbc:mysql://localhost:3306/userdb prop.username = root prop.password =
- 把外部 properties 属性文件引入到spring配置文件中
- 引入context名称空间
- 在spring配置文件中使用标签引入
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 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:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClassName}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.username}"></property> <property name="password" value="${prop.password}"></property> </bean> </beans>
12.IOC 操作 Bean 管理(基于注解)
-
什么是注解
- 代码里面特殊的格式,格式:@注解名称(属性名称=属性值,属性名称=属性值)
- 使用注解 :注解的作用在类的上面,方法上面,属性上面
- 使用注解目的:简化xml配置
-
Spring针对Bean管理中创建对象提供注解
- @Component
- @Service
- @Controller
- @Repository
*上面四个注解功能是一样的,都可以用来创建bean实例
-
基于注解方式创建对象
-
第一步引入依赖:spring-aop-5.2.9.RELEASE.jar
-
第二步开启组件扫描:
<?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" 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:component-scan base-package="com.bgu.edu"></context:component-scan> </beans>
-
第三步
package com.bgu.edu; import org.springframework.stereotype.Component; //在注解里面value属性值可以省略不写 //如果不写 value 默认值是类的名称的首字母小写 //UserService----->userService @Component(value = "userService") public class UserService { public void add(){ System.out.println("add-----"); } }
-
-
-
基于注解方式实现属性注入
-
@AutoWired:根据属性类型进行自动装配
第一步:把service和dao对象创建,在servic和dao里添加创建对象注解
第二步:在service注入dao对象,在service类添加dao类型属性,在属性上使用注解
package com.bgu.edu; import com.bgu.edu.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; //在注解里面value属性值可以省略不写 //如果不写 value 默认值是类的名称的首字母小写 //UserService----->userService @Component(value = "userService") public class UserService { @Autowired private UserDao userDao; public void add(){ System.out.println("add-----"); } }
-
@Qualifier:根据属性名称进行注入
这个 @Qualifier注解的使用,需要和上面的@AutoWired配合使用:一个接口可能有多个实现类,@AutoWired无法准确找到我们需要的实现类,通过 @Qualifier指定我们具体实现众多实现类的哪一个
package com.bgu.edu.service; import com.bgu.edu.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; //在注解里面value属性值可以省略不写 //如果不写 value 默认值是类的名称的首字母小写 //UserService----->userService @Component(value = "userService") public class UserService { @Autowired @Qualifier(value = "userDaoImpl") private UserDao userDao; public void add(){ System.out.println("Service_add"); userDao.add(); } }
-
@Resource:可以根据类型注入,可以根据名称注入
package com.bgu.edu.service; import com.bgu.edu.dao.UserDao; import org.springframework.stereotype.Component; import javax.annotation.Resource; //在注解里面value属性值可以省略不写 //如果不写 value 默认值是类的名称的首字母小写 //UserService----->userService @Component(value = "userService") public class UserService { // private UserDao userDao; //@Resource //根据类型注入 @Resource(name = "userDaoImpl")//根据类名称注入 private UserDao userDao; public void add(){ System.out.println("Service_add"); userDao.add(); } }
-
@Value:注入普通数据类型属性
@Value(value = "abc") private String name;
5.完全注解开发
-
创建配置类:替代xml配置文件、
-
编写测试类
@Test public void test2(){ //加载配置类 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService",UserService.class); userService.add(); }
-
(四)AOP
0.AOP概念
- 什么是AOP?
- AOP:变相切面编程
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑之间的耦合度降低,提高程序的可重用性,同时提高开发效率
- 通俗描述:不通过修改源代码的方式,在主干功能里面添加功能
1.AOP底层原理
- AOP底层使用动态代理
- 有两种情况的动态代理
- 第一种情况有接口,使用JDK动态代理
- 创建接口实现类的代理对象,实现功能增强
- 第二种情况没有接口,使用CGLIB动态代理
- 创建当前类的子类代理对象,实现功能增强
2.AOP(JDK动态代理)
-
使用 JDK动态代理,是使用Proxy类里面的方法创建代理对象
- java.lang.Object
- java.lang.reflect.Proxy
- 调用 newProxyInstans方法,方法有三个参数
- 第一个参数:ClassLoader loder
- 第二个参数:增强方法所在的类,这个类实现的接口(可以写多个)
- 第三个参数:实现里面的接口 InvocationHandler,创建代理对象,写增强方法
- java.lang.Object
-
JDK动态代理
-
创建接口,定义方法
-
创建接口实现类,实现方法
-
使用Proxy类,创建接口的代理对象
package com.bgu.edu; import java.lang.reflect.Array; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; public class JDKProxy { public static void main(String[] args) { //创建接口实现类代理对象 Class[] interfaces = {UserDao.class}; UserDaoImlp userDao = new UserDaoImlp(); UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int result = dao.add(1,2); System.out.println(result); } } //创建代理类对象 class UserDaoProxy implements InvocationHandler { //1.把创建是谁的代理对象,把谁传过来 //有参数的构造 private Object obj; public UserDaoProxy(Object obj) { this.obj = obj; } //增强逻辑 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //方法之前 System.out.println("方法之前:" + method.getName() + "::" + Arrays.toString(args)); //被增强方法执行 Object res = method.invoke(obj, args); //方法之后 System.out.println("方法之后" + obj); return res; } }
-
3.AOP(术语)
- 连接点
- 类里面的拿些方法能被增强,这个方法就叫连接点
- 切入点
- 实际被真正增强的方法就是切入点
- 通知(增强)
- 实际增强的逻辑代码部分就是通知(增强)
- 有多种类型
- 1.前置通知
- 2.后置通知
- 3.环绕通知
- 4.异常通知
- 5.最终通知 :finally
- 切面
- 是动作
- 把通知应用加到切入点的过程
4.AOP操作(准备)
- Spring框架中一般基于AspectJ 实现AOP操作
- 什么是AspectJ并不是Spring的组成部分,他是一个独立的AOP框架,一般把AspectJ和Spring一起使用,进行AOP操作
- 基于AspectJ 实现AOP操作
- 基于xml配置文件实现
- 基于注解方式实现(使用)
- 在项目的工程里引入依赖AspectJ
- spring-aspects-5.2.9.RELEASE.jar
- com.springsource.net.sf.cglib-2.2.0.jar
- com.springsource.org.aopalliance-1.0.0.jar
- com.springsource.org.aspectj.weaver-1.6.4.RELEASE.jar
- 切入点的表达式
- 切入点表达式的作用:知道对哪个类的哪个方法进行加强
- 语法结构
- execution( [权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]))
- 举例1:
- 对 com.bgu.edu.UserDao 类里面的add方法进行增强
- execution(* com.bgu.edu.UserDao.add(…))
- 举例2:对 com.bgu.edu.UserDao 类里面的所有方法进行增强
- execution(* com.bgu.edu.UserDao.*(…))
- 举例3:对 com.bgu.edu包 里面的所有类的所有方法进行增强
- execution(* com.bgu.edu.UserDao*.*(…))
5.AOP操作(AspectJ注解)
-
创建类,在类里面定义方法
package com.bgu.edu.aopanno; //被增强的类 public class User { public void add(){ System.out.println("User_add"); } }
-
创建增强类(编写增强逻辑)
-
在增强类里面,创建方法,让不同的方法代表不同的通知类型
package com.bgu.edu.aopanno; public class UserProxy { //前置通知 public void before(){ System.out.println("before....."); } }
-
-
进行通知配置
-
在spring配置文件中,开启注解扫描
-
使用注解创建两个对象
-
增强的类上面添加注解:@Aspect
package com.bgu.edu.aopanno; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class UserProxy { //前置通知 public void before(){ System.out.println("before....."); } }
-
在spring配置文件生成代理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--开启注解扫描--> <context:component-scan base-package="com.bgu.edu.aopanno"></context:component-scan> <!--开启Aspect生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
-
-
配置不同类型的通知
-
在增强类的利埃纳,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
package com.bgu.edu.aopanno; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class UserProxy { //前置通知 //@Before注解表示作为前置通知 @Before(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void before(){ System.out.println("before....."); } //最终通知 @After(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void afer(){ System.out.println("after......"); } //后置通知 @AfterReturning(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void aferReturning(){ System.out.println("AfterReturning......"); } @AfterThrowing(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void aferThrowing(){ System.out.println("AfterThrowing......"); } @Around(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕之前......"); proceedingJoinPoint.proceed(); System.out.println("环绕之后......"); } }
-
TestAopanno测试调用
package com.bgu.edu.test; import com.bgu.edu.aopanno.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAop { @Test public void testAopanno(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); User user = context.getBean("user", User.class); user.add(); } }
-
-
相同切入点抽取
package com.bgu.edu.aopanno; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class UserProxy { @Pointcut(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void pointdemo(){ } //前置通知 //@Before注解表示作为前置通知 @Before(value = "pointdemo()") public void before(){ System.out.println("before....."); } //最终通知 @After(value = "pointdemo()") public void afer(){ System.out.println("after......"); } //后置通知 @AfterReturning(value = "pointdemo()") public void aferReturning(){ System.out.println("AfterReturning......"); } @AfterThrowing(value = "pointdemo()") public void aferThrowing(){ System.out.println("AfterThrowing......"); } @Around(value = "pointdemo()") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕之前......"); proceedingJoinPoint.proceed(); System.out.println("环绕之后......"); } }
-
多个增强类可以设置优先级
-
在增强类的上面添加注解@Order(数值类型),数字越小优先级越高
package com.bgu.edu.aopanno; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Aspect @Order(value = 1) public class PersonProxy { @Before(value = "execution(* com.bgu.edu.aopanno.User.add(..))") public void before(){ System.out.println("PersonProxy_before....."); } }
-
(“AfterReturning…”);
}
@AfterThrowing(value = “pointdemo()”)
public void aferThrowing(){
System.out.println(“AfterThrowing…”);
}
@Around(value = "pointdemo()")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前......");
proceedingJoinPoint.proceed();
System.out.println("环绕之后......");
}
}
6. 多个增强类可以设置优先级
- 在增强类的上面添加注解@Order(数值类型),数字越小优先级越高
```java
package com.bgu.edu.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(value = 1)
public class PersonProxy {
@Before(value = "execution(* com.bgu.edu.aopanno.User.add(..))")
public void before(){
System.out.println("PersonProxy_before.....");
}
}
```