1、 Spring 是轻量级的开源的 JavaEE 框架
2、 Spring 可以解决企业应用开发的复杂性
3、 Spring 有两个核心部分: IOC 和 Aop
(1) IOC:控制反转,把创建对象过程交给 Spring 进行管理
(2) Aop:面向切面,不修改源代码进行功能增强
4、 Spring 特点 :
(1)方便解耦,简化开发
(2) Aop 编程支持
(3)方便程序测试
(4)方便和其他框架进行整合
(5)方便进行事务 *** 作
(6)降低 API 开发难度
二、IOC 容器 1.IOC的底层原理-
IOC:
①控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
②使用 IOC 目的:为了耦合度降低
-
底层原理: xml解析、工厂模式、反射
-
讲解:最原始的方法如下,使用工厂模式可以降低耦合但不是降低到最低限度
-
在Spring中,使用 IOC 容器可以降低耦合.使用IOC对当前进行改造
-
IOC 实现过程:
-
第一步,xml 配置文件,配置创建的对象
-
<bean id="user" class="com.syy.spring5.User">bean>
-
第二步,有 service 类和 dao 类,创建工厂类
-
class UserFactory{ public static UserDao getDao(){ //1.xml解析,得到bean中class属性的值 String classValue = class属性值; //2.通过反射创建对象 Class clazz = Class.forName(classValue);//通过反射得到字节码文件 return (UserDao)clazz.newInstance();//创建对象 } }
-
-
IOC 的思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
-
Spring 提供 IOC 容器实现的两种方式(两个接口):
-
BeanFactory : IOC 容器最基本实现,是Spring内部的使用接口,不提供开发人员进行使用
注:在加载配置文件的时候不会创建对象,在获取(使用)对象的时候才会创建对象
-
ApplicationContext : BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员使用
注:在加载配置文件的时候就会把配置文件中的对象进行创建
-
-
ApplicationContext的主要实现类
- FileSystemXmlApplicationContext
- 需要写文件在系统中的位置(带盘符路径),文件全路径
- ClassPathXmlApplicationContext
- 路径为src内的文件,类路径
- FileSystemXmlApplicationContext
- 什么是Bean管理
- Bean管理指的是两个 *** 作:
- Spring 创建对象
- Spring 注入属性 – 设置值
- Bean管理指的是两个 *** 作:
- Bean 管理 *** 作的两种方式
- 基于 xml 配置文件方式实现
- 基于注解方式实现
-
<bean id="user" class="com.syy.spring5.User">bean>
-
在Spring配置文件中,使用 bean 标签,标签中添加对应属性,就可以实现对象创建
-
常用的属性:
- id 属性:唯一标识(别名),通过标识获取对象,不能加特殊符号
- class 属性:类全路径(包类路径)
- name 属性:和id相同,但可以加特殊符号.不常用
-
创建对象时,默认是执行无参构造方法完成对象创建
- DI : 依赖注入,就是注入属性
- 注入方式:
2.1 使用set方法进行注入
-
创建类,定义属性和对应的set方法
public class User { //定义属性 private String uname; private Integer age; //创建对应的set方法 public void setUname(String uname) { this.uname = uname; } public void setAge(Integer age) { this.age = age; } }
-
在Spring配置文件配置对象创建,配置属性注入
<bean id="user" class="com.syy.spring5.User"> <property name="uname" value="lili">property> <property name="age" value="11">property> bean>
2.2 使用有参数构造进行注入
- 创建类,定义属性,创建属性对应有参构造方法
public class User { private String uname; private Integer age; //有参构造方法 public User(String uname, Integer age) { this.uname = uname; this.age = age; } }
- 在Spring配置文件中进行配置
<bean id="user" class="com.syy.spring5.User"> <constructor-arg name="uname" value="张三">constructor-arg> <constructor-arg name="age" value="54">constructor-arg> bean>
2.3 p名称空间注入(了解)
- p名称空间注入底层也是set方法注入,只是简化了xml配置方法
- 第一步,添加p名称空间在配置文件中 – 将下行代码添加到 beans 标签中
xmlns:p="http://www.springframework.org/schema/p"
- 第二步,进行属性注入,在bean标签里面进行 *** 作
<bean id="user" class="com.syy.spring5.User" p:uname="李四" p:age="12">bean>
-
-
xml 注入其他类型属性
3.1 字面量 – 属性的固定值
- null值
<property name="address"> <null/> property>
-
属性包括特殊符号 – 例<<南京>>
- 将<>进行转义: < ; >
- 将带特殊符号内容写到CDATA
<property name="address"> <value>>]]>value> property>
3.2 注入外部属性 – 外部bean
3.2.1 创建两个类service类和dao类
3.2.2 在service调用dao里面的方法 – 引入外部bean
- UserDao代码:
public interface UserDao { void update(); }
- UserDaoImpl代码:
public class UserDaoImpl implements UserDao { @Override public void update() { System.out.println("dao update......"); } }
- UserService代码:
public class UserService { //创建UserDao类型属性,生成set方法 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add(){ System.out.println("service add ..........."); //调用dao中方法 userDao.update(); } }
3.2.3 在Spring配置文件中进行配置
<bean id="userService" class="com.syy.spring5.service.UserService"> <property name="userDao" ref="userDaoImpl">property> bean> <bean id="userDaoImpl" class="com.syy.spring5.dao.impl.UserDaoImpl">bean>
3.3 注入外部属性 – 内部bean
3.3.1 举例说明:在数据库中有
- 一对多关系:部门和员工
- 一个部门有多个员工,一个员工属于一个部门
- 在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
3.3.2 内部bean的实现
①创建部门类和员工类
部门类:
public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } }
员工类:
public class Emp { private String ename; private String gender; //员工属于某一个部门,使用对象形式表示 private Dept dept; public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } public void setDept(Dept dept) { this.dept = dept; } }
②在Spring配置文件中进行配置
<bean id="emp" class="com.syy.spring5.Emp"> <property name="ename" value="lucy">property> <property name="gender" value="女">property> <property name="dept"> <bean id="dept" class="com.syy.spring5.Dept"> <property name="dname" value="安保部">property> bean> property> bean>
3.4 注入外部属性 – 级联赋值
级联赋值:同时向有关联的类中赋值(向多个实体类赋值)
- 第一种写法:部门类和员工类代码不变,配置文件修改为:
<bean id="emp" class="com.syy.spring5.Emp"> <property name="ename" value="lucy">property> <property name="gender" value="女">property> <property name="dept" ref="dept">property> bean> <bean id="dept" class="com.syy.spring5.Dept"> <property name="dname" value="财务部">property> bean>
-
第二写法:
-
在Emp类中生成dept的get方法,用来得到对象
-
配置文件修改
<bean id="emp" class="com.syy.spring5.Emp"> <property name="ename" value="lucy">property> <property name="gender" value="女">property> <property name="dept" ref="dept">property> <property name="dept.dname" value="技术部">property> bean> <bean id="dept" class="com.syy.spring5.Dept">bean>
-
-
xml注入集合属性
4.1 注入数组类型属性
4.2 注入List集合类型属性
4.3 注入Map集合、set集合类型属性
①创建类,定义数组、list、map、set类型属性,生成对应set方法
public class Stu {
//1.数组类型属性
private String[] courses;
//2.list集合类型属性
private List<String> list;
//3.map集合类型属性
private Map<String,String> maps;
//4.set集合类型
private Set<String> sets;
public void setCourses(String[] courses) {
this.courses = courses;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
}
②在Spring配置文件中进行配置
<bean id="stu" class="com.syy.spring5.collectiontype.Stu">
<property name="courses">
<array>
<value>java课程value>
<value>spring课程value>
array>
property>
<property name="list">
<list>
<value>张三value>
<value>李四value>
list>
property>
<property name="maps">
<map>
<entry key="Java" value="java">entry>
<entry key="Spring" value="Spring">entry>
map>
property>
<property name="sets">
<set>
<value>Mysqlvalue>
<value>Redisvalue>
set>
property>
bean>
4.4 在集合中设置对象类型值
①创建多个course对象
<bean id="course1" class="com.syy.spring5.collectiontype.Courses">
<property name="cname" value="Spring框架">property>
bean>
<bean id="course2" class="com.syy.spring5.collectiontype.Courses">
<property name="cname" value="Mybatis框架">property>
bean>
<bean id="course3" class="com.syy.spring5.collectiontype.Courses">
<property name="cname" value="SpringMVC框架">property>
bean>
②在Stu对象中注入list集合类型,值为对象
<property name="coursesList">
<list>
<ref bean="course1">ref>
<ref bean="course2">ref>
<ref bean="course3">ref>
list>
property>
ref中的bean值为courses对象的id值
4.5 把集合注入部分提取出来
①在Spring配置文件中引入名称空间util
<beans ...
xmlns:util="http://www.springframework.org/schema/util"
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集合注入提取
<util:list id="booklist">
<value>易筋经value>
<value>九阳神经value>
<value>一指禅value>
util:list>
<bean id="book" class="com.syy.spring5.collectiontype.Book">
<property name="list" ref="booklist">property>
bean>
(3) FactotyBean – 内置bean
-
Spring有两种类型,一种普通bean,另外一种工厂bean(FactoryBean)
-
普通bean:在配置文件中定义 bean 类型就是返回类型
-
工厂bean:在配置文件中定义 bean 类型可以和返回类型不一样
- 第一步,创建类,让这个类作为工厂bean,实现接口FactoryBean
- 第二步,实现接口中的方法,在实现的方法中定义返回的bean类型
public class MyBean implements FactoryBean<Courses> { //定义返回bean @Override public Courses getObject() throws Exception { Courses courses = new Courses(); courses.setCname("abc"); return courses; } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } }
配置文件中:
<bean id="myBean" class="com.syy.spring5.factorybean.MyBean">bean>
测试类代码:
@Test public void test3() { ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Courses course = context.getBean("myBean", Courses.class); System.out.println(course); }
-
- 在Spring中,设置创建bean实例是单实例还是多实例
- 在Spring中,默认情况下,bean是单实例对象 – 验证实例地址值是否相同
- 测试方法类:
@Test
public void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Book book1 = context.getBean("book", Book.class);
Book book2 = context.getBean("book", Book.class);
System.out.println(book1);
System.out.println(book2);
}
com.syy.spring5.collectiontype.Book@2f8f5f62 com.syy.spring5.collectiontype.Book@2f8f5f62 – 结果相同,默认为单实例 |
---|
-
如何设置单实例还是多实例
-
在Spring配置文件bean标签里面有属性 (scope) 用来设置单实例还是多实例
-
scope 属性值:
- 默认值, singleton ,表示是单实例对象
- prototype ,表示是多实例对象
-
<bean id="book" class="com.syy.spring5.collectiontype.Book" scope="prototype"> <property name="list" ref="booklist">property> <property name="coursesList" ref="courseslist">property> bean>
-
com.syy.spring5.collectiontype.Book@1068e947
com.syy.spring5.collectiontype.Book@7dc222ae – 结果不同,创建实例为多实例 -
singleton 和 prototype 的区别:
- singleton 为单实例 , prototype 为多实例
- 设置scope值为singleton 时,加载Spring配置文件时就会创建单实例对象
- 设置scope值为 prototype 时,不是在加载Spring配置文件时创建对象,而是在调用getBean方法时创建多实例对象
-
-
生命周期:从对象创建到对象销毁
-
bean的生命周期:
-
通过构造器创建bean实例(无参数构造)
-
为bean的属性设置值和对其他bean引用(调用set方法)
-
调用bean的初始化的方法(需要进行配置初始化的方法)
-
bean可以使用了(对象获取到了)
-
当容器关闭时,调用bean的销毁的方法(需要进行配置销毁的方法)
-
-
演示bean生命周期
-
public class Orders { //无参数构造 public Orders() { System.out.println("第一步 执行无参数构造创建bean实例"); } private String oname; public void setOname(String oname) { this.oname = oname; System.out.println("第二步 调用set方法设置属性值"); } //创建执行的初始化的方法 public void initMethod() { System.out.println("第三步 执行初始化的方法"); } //创建执行的销毁的方法 public void destroyMethod() { System.out.println("第五步 执行销毁的方法"); } }
-
配置文件:
-
<bean id="orders" class="com.syy.spring5.factorybean.Orders" init-method="initMethod" destroy-method="destroyMethod"> <property name="oname" value="李四">property> bean>
-
测试类代码:
-
@Test public void test4(){ // ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); //注意:ApplicationContext没有close方法,需要使用子接口 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); Orders orders= context.getBean("orders",Orders.class); System.out.println("第四步 获取创建bean实例对象"); System.out.println(orders); //手动让bean实例销毁 context.close(); }
-
输出结果:
-
第一步 执行无参数构造创建bean实例
第二步 调用set方法设置属性值
第三步 执行初始化的方法
第四步 获取创建bean实例对象
Orders{oname=‘李四’}
第五步 执行销毁的方法 -
bean的后置处理器,bean的生命周期有七步
- 通过构造器创建bean实例(无参数构造)
- 为bean的属性设置值和对其他bean引用(调用set方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization – 可以定制一些在初始化之前的业务
- 调用bean的初始化的方法(需要进行配置初始化的方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization – 可以定制一些在初始化之前的业务
- bean可以使用了(对象获取到了)
- 当容器关闭时,调用bean的销毁的方法(需要进行配置销毁的方法)
-
演示添加后置管理器效果
-
创建类,实现接口BeanPostProcessor,创建后置处理器(会对所有bean实例添加后置管理器)
-
public class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之前的方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之后的方法"); return bean; } }
-
配置文件中,配置后置管理器
-
<bean id="orders" class="com.syy.spring5.factorybean.Orders" init-method="initMethod" destroy-method="destroyMethod"> <property name="oname" value="李四">property> bean> <bean id="myBeanPost" class="com.syy.spring5.factorybean.MyBeanPost">bean>
-
测试结果:
-
第一步 执行无参数构造创建bean实例
第二步 调用set方法设置属性值
在初始化之前的方法
第三步 执行初始化的方法
在初始化之后的方法
第四步 获取创建bean实例对象
Orders{oname=‘李四’}
第五步 执行销毁的方法
-
-
自动装配:根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
-
实现自动装配过程 – bean标签属性 autowire,配置自动装配
-
根据属性名称自动注入 – byName ,注入值bean的id值和类属性名称一样
<bean id="emp" class="com.syy.spring5.autowire.Emp" autowire="byName">bean>
-
根据属性类型自动注入 – byType
不能定义多个bean,
<bean id="emp" class="com.syy.spring5.autowire.Emp" autowire="byType">bean>
-
-
引入外部属性文件配置数据库连接池
-
配置德鲁伊连接池,引入德鲁伊连接池依赖jar包
-
创建外部属性文件,properties格式文件,写数据库信息
-
#建议使用prop.名字的形式,以保证不会冲突 prop.driverClass=com.mysql.jdbc.Driver prop.url=jdbc:mysql://localhost:13306/userdb prop.userName=root prop.password=root
-
把外部properties属性文件引入到spring配置文件中
-
引入context名称空间
-
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="... http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
-
在spring配置文件使用标签引入外部属性文件
-
<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClass}">property> <property name="url" value="${prop.url}">property> <property name="username" value="${prop.userName}">property> <property name="password" value="${prop.password}">property> bean>
-
-
-
注解:
- 注解是代码特殊标记,格式:@注解名称(属性名称 = 属性值,属性名称 = 属性值…)
- 使用注解,注解作用在类上面,方法上面,属性上面
- 使用注解的目的:简化xml配置
-
Spring针对Bean管理中创建对象提供注解
- @Component --> 普通类中
- @Service --> 业务逻辑层/service层
- @Controller --> web层
- @Repository --> DAO层/持久层
- 上面四个注解功能是一样的,都可以用来创建bean实例
-
基于注解方式实现对象创建
-
第一步,映入依赖
-
第二步,开启组件扫描 – 不开启,Spring无法找到类
-
<context:component-scan base-package="com.syy">context:component-scan>
-
使用组件扫描Spring就会知道是使用注解方式,就会在包下扫描所有文件,找到有注解的文件,创建对象
-
-
第三步,创建类,在类上面添加创建对象注解
-
value属性值可以省略不写
-
默认值是类名称,首字母小写
-
@Service(value = "userService") //等于
public class UserService { public void add(){ System.out.println("service add......."); } }
-
-
开启组件扫描细节配置 – 可以设置扫描哪些内容
-
示例一:
-
use-default-filters=“false” 表示现在不使用默认 filter,自己配置 filter
context:include-filter ,设置扫描哪些内容-
<context:component-scan base-package="com.atguigu" use-defaultfilters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> context:component-scan>
-
-
示例二:
-
context:exclude-filter: 设置哪些内容不进行扫描
-
<context:component-scan base-package="com.atguigu"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> context:component-scan>
-
-
-
基于注解方式实现属性注入
-
@Autowired : 根据属性类型进行自动装配
-
第一步,把service和dao对象创建,在service和dao类添加创建对象注解
-
第二步,在service注入dao对象,在service类添加dao类型属性,再熟悉上面使用注解
-
@Service public class UserService { //定义dao类型属性,不需要添加set方法 @Autowired private UserDao userDao; public void add(){ System.out.println("service add......."); } }
-
-
@Qualifier : 根据名称注入
-
这个@Qualifier注解的使用,和上面@Autowired一起使用
-
@Service public class UserService { @Autowired @Qualifier(value = "userDaoImpl") //一个接口可能会有多个实现类,通过名称可以指定是哪个实现类 private UserDao userDao; public void add(){ System.out.println("service add......."); } }
-
-
@Resource : 可以根据类型注入,可以根据名称注入
-
@Resource(name = "userDaoImpl") private UserDao userDao;
-
-
@Value : 注入普通类型
-
@Value(value = "李四") private String name;
-
-
-
完全注解开发
-
创建配置类,替代xml配置文件
@Configuration @ComponentScan(basePackages = {"com.syy"}) public class SpringConfig {
-
编写测试类
@Test public void test2(){ ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); // ApplicationContext context =new ClassPathXmlApplicationContext("bean2.xml"); UserService userService = context.getBean("userService",UserService.class); System.out.println(userService); userService.add(); }
-
AOP : 面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而是的业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.
通俗描述 : 不通过修改源代码方式,在主干功能里面添加新功能
2.AOP底层使用动态代理两种情况:
第一种,有接口情况,使用 JDK 动态代理 - 创建接口的实现类代理对象,增强类的方法
第二种,没有接口情况,使用 CGLIB 动态代理 - 创建子类的代理对象,增强类的方法
3.AOP术语- 连接点 - 类里面哪些方法可以被增强,这些方法称为连接点
- 切入点 - 实际被真正增强的方法,称为切入点
- 通知(增强) - 实际增强的逻辑部分称为通知(增强)
- 通知有多种类型:
- 前置通知 - 方法之前执行 - @Before
- 后置通知 - 方法之后执行 - @AfterReturning
- 在方法之后执行,有异常不执行
- 环绕通知 - 方法前后都执行 - @Around
- 异常通知 - 出现了异常后执行 - @AfterThrowing
- 最终通知 - 类似于try,catch中finally中的代码 - @After
- 在方法之后执行,不管有没有异常都执行
- 通知有多种类型:
- 切面 - 是动作,把通知应用到切入点过程
- AspectJ不是Spring组成部分,是独立的AOP框架,一般把AspectJ和Spring框架一起使用,进行AOp *** 作
- 基于xml配置文件实现
- 基于注解方式实现(常用)
- 切入点表达式作用:知道对哪个类里面的哪个方法进行增强
- 语法结构:execution([权限修饰符] [返回类型] [类全路径] [方法名称] [参数列表])
- 举例:
- 对 com.atguigu.dao.BookDao 类里面的 add 进行增强
- execution(* com.atguigu.dao.BookDao.add(…))
- 对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强
- execution(* com.atguigu.dao.BookDao.* (…))
- 对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强
- execution(* com.atguigu.dao.. (…))
- 对 com.atguigu.dao.BookDao 类里面的 add 进行增强
public class User {
public void add(){
System.out.println("未增强代码add..");
}
}
(2) 创建增强类(编写增强逻辑)
public class UserProxy {
public void before(){
System.out.println("前置通知方法add....");
}
}
(3) 进行通知的配置
- 引入context和aop的名称空间,开启注解扫描和开启代理对象
<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"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:component-scan base-package="com.syy.spring5">context:component-scan>
<aop:aspectj-autoproxy>aop:aspectj-autoproxy>
beans>
- 使用注解创建对象
@Component
public class User {...}
@Component
public class UserProxy {...}
- 在增强类上添加注解 @AspectJ
@Component
@Aspect
public class UserProxy {...}
(4) 配置不同类型的通知
@Component
@Aspect
public class UserProxy {
@Before(value = "execution(* com.syy.spring5.dao.User.add(..))")
public void before() {
System.out.println("前置通知方法add....");
}
@AfterReturning(value = "execution(* com.syy.spring5.dao.User.add(..)))")
public void afterReturning() {
System.out.println("afterReturning.........");
}
//最终通知
@After(value = "execution(* com.syy.spring5.dao.User.add(..))")
public void after() {
System.out.println("after.........");
}
//异常通知
@AfterThrowing(value = "execution(* com.syy.spring5.dao.User.add(..))")
public void afterThrowing() {
System.out.println("afterThrowing.........");
}
//环绕通知
@Around(value = "execution(* com.syy.spring5.dao.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws
Throwable {
System.out.println("环绕之前.........");
//被增强的方法执行
proceedingJoinPoint.proceed();
System.out.println("环绕之后.........");
}
}
(5)相同的切入点抽取
创建一个方法进行相同切入点的抽取,通知方法在value中调用方法
@Pointcut(value = "execution(* com.syy.spring5.dao.User.add(..))")
public void pointdemo(){
}
@Before(value = "pointdemo()")
public void before() {
System.out.println("前置通知方法add....");
}
(6) 设置增强类的优先级
当有多个增强类对同一个方法进行增强时,可以在增强类上添加注解 @Order(数字类型值),数字类型值越小优先级越高
@Component
@Aspect
@Order(1)
public class UserProxy {...}
(7) 完全注解开发
创建配置类,不需要创建xml配置文件
@Configuration
@ComponentScan(basePackages = {"com.syy"})
@EnableAspectJAutoProxy(proxyTargetClass = true)//替代
public class ConfigAop {...}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)