课程内容介绍
1.Spring 框架概述
Spring 框架概述
1.Spring是轻量级的开源的JavaEE框架
2.Spring可以解决企业应用开发的复杂性
3.Spring有两个核心部分:IOC和Aop
(1) IOC:控制反转,把创建对象过程交给Spring进行管理
(2) Aop:面向切面,不修改源代码进行功能增强
4.Spring特点
(1)方便解耦,简化开发
(2)Aop编程支持
(3)方便程序测试
(4)方便和其他框架进行整合
(5)方便进行实务操作
(6)降低API开发难度
2.IOC容器
IOC(概念和原理)
1、什么是IOC
(1)控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
(2)使用IOC目的:为了耦合度降低
(3)做入门案例就是IOC实现
2、IOC底层原理
(1)xml解析、工厂模式、反射
3、画图讲解IOC底层原理
IOC(BeanFactory接口)
1、IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
2、Spring提供IOC容器实现的两种方式:(两个接口)
(1)Bean Factory:IOC容器基本实现,是Spring内部的使用接口,不提倡开发人员进行使用
*加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
*加载配置文件的时候就会把在配置文件的对象进行创建
3、ApplicationContext接口的实现类
IOC操作Bean管理(概念)
1、什么是Bean管理
(0)Bean管理指的是两个操作
(1)Spring创建对象
(2)Spring注入属性
2、Bean管理操作由两种方式
(1)基于xml配置文件方式实现
(2)基于注解方式实现
IOC操作Bean管理(基于xml方式)
1、基于xml方式创建对象
(1)在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
(2)在bean标签有很多属性,介绍常用的属性
*id属性:唯一标识
*class属性:类全路径(包类路径)
(3)创建对象时候,默认也是执行无参数构造方法完成对象创建
2、基于xml方式注入属性
(1)DI:依赖注入,就是注入属性
3、第一种注入方式:使用set方法进行注入
(1)创建类,定义属性和对应的set方法
/** * 演示使用set方法进行注入属性 * @author ajin * @create 2022-10-03 15:13 */ 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; } }
(2)在spring配置文件配置对象创建,配置属性注入
4、第二种注入方式:使用有参数构造进行注入
(1)创建类,定义属性,创建属性对应有参数构造方法
/** 使用有参构造注入 * @author ajin * @create 2022-10-04 3:06 */ public class Orders { //属性 private String oname; private String address; //有参数构造 public Orders(String oname, String address) { this.oname = oname; this.address = address; } public void Test(){ System.out.println(oname+"::"+address); } }
(2)在spring配置文件中进行配置
<!-- 3 有参数构造注入属性 --> <bean id="orders" class="com.ajin.spring5.Orders"> <constructor-arg name="oname" value="电脑"></constructor-arg> <constructor-arg name="address" value="China"></constructor-arg> </bean>
5、p名称空间注入(了解)
(1)使用p名称空间注入,可以简化基于xml配置方式
第一步 添加p名称空间在配置文件中
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
第二步 进行属性注入,在bean标签里面进行操作
<!-- 4 set 方法注入属性 --> <bean id="book" class="com.ajin.spring5.Book" p:bname="九阳神功" p:bauthor="无名氏"> </bean>
IOC操作Bean管理(xml注入其他类型属性)
1、字面量
(1)null值
<!-- null值 --> <property name="address"> <null/> </property>
(2)属性值包含特殊符号
<!-- 属性值包含特殊符号 1. 把<>进行转义<> 2. 把带特殊符号内容写道CDATA --> 1.<property name="address" value="<<南京>>"></property> 2. <property name="address"> <value><![CDATA[<<南京>>]]></value> </property>
2、注入属性-外部 bean
(1)创建两个类service类和dao类
(2)在service调用dao里面的方法
(3)在spring配置文件中进行配置
/** * @author ajin * @create 2022-10-04 16:18 */ public class UserService { //创建UserDao类型属性,生成set方法 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add(){ System.out.println("service add....."); userDao.update(); } }
<!-- 1 service和dao对象创建 --> <bean id="userService" class="com.ajin.spring5.service.UserService"> <!-- 注入userDao对象 name属性值:类里面属性名称 ref属性:创建userDao对象bean标签id值 --> <property name="userDao" ref="userDao"></property> </bean> <bean id="userDao" class="com.ajin.spring5.dao.UserDaoImpl"></bean>
3、注入属性-内部 bean
(1)一对多关系:部门和员工
一个部门有多个员工,一个员工属于一个部门
部门是一,员工是多
(2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
/** 部门类 * @author ajin * @create 2022-10-04 19:43 */ public class Dept { private String dname; public void setDname(String dname) { this.dname = dname; } }
/** 员工类 * @author ajin * @create 2022-10-04 19:44 */ public class Emp { private String ename; private String gender; //员工属于某一个部门,使用对象形式表示 private Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } }
(3)在spring配置文件中进行配置
4、注入属性-级联赋值
(1)第一种写法
<!--级联赋值--> <bean id="emp" class="com.ajin.spring5.bean.Emp"> <!--设置两个普通属性--> <property name="ename" value="小白"></property> <property name="gender" value="女"></property> <!--级联赋值--> <property name="dept" ref="dept"></property> </bean> <bean id="dept" class="com.ajin.spring5.bean.Dept"> <property name="dname" value="财务部"></property> </bean>
(2)第二种写法
<!--级联赋值--> <bean id="emp" class="com.ajin.spring5.bean.Emp"> <property name="dept.dname" value="技术部"></property> </bean>
IOC操作 Bean 管理(xml注入集合属性)
1、注入数组类型属性
2、注入List集合类型属性
3、注入Map集合类型属性
(1)创建类,定义数组、list、map、set类型属性,生成对应set方法
/** * @author ajin * @create 2022-10-05 1:36 */ 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; }
(2)在spring配置文件进行配置
<!-- 集合类型属性注入 --> <bean id="stu" class="com.ajin.spring5.collectiontype.Stu"> <!--数组类型属性注入--> <property name="courses"> <array> <value>java课程</value> <value>数据库课程</value> </array> </property> <!--list类型属性注入--> <property name="list"> <list> <value>小白</value> <value>大白</value> </list> </property> <!--map类型属性注入--> <property name="maps"> <map> <entry key="1" value="爱"></entry> <entry key="2" value="你"></entry> </map> </property> <!--set类型属性注入--> <property name="sets"> <set> <value>agd</value> <value>faeef</value> </set> </property> </bean>
4、在集合里面设置对象类型值
<!--创建多个course对象--> <bean id="coursel" class="com.ajin.spring5.collectiontype.Course"> <property name="cname" value="Spring5框架"></property> </bean> <bean id="course2" class="com.ajin.spring5.collectiontype.Course"> <property name="cname" value="Spring5框架"></property> </bean>
<!--注入list集合类型,值是对象--> <property name="courseList"> <list> <ref bean="coursel"></ref> <ref bean="course2"></ref> </list> </property>
5、把集合注入部分提取出来
(1)在spring配置文件中引入名称空间util
<?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: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">
(2)使用util标签完成list集合注入提取
<!-- 1 提取list集合类型属性注入 --> <util:list id="bookList"> <value>三体</value> <value>活着</value> <value>人间失格</value> </util:list> <!-- 2 提取list集合类型属性注入使用 --> <bean id="book" class="com.ajin.spring5.collectiontype.Book"> <property name="list" ref="bookList"></property> </bean>
IOC操作Bean管理(FactoyBean)
1、Spring有两种类型bean,一种普通bean,另一种工厂bean(FactoryBean)
2、普通bean:在配置文件中定义bean类型就是返回类型
3、工厂bean:在配置文件定义bean类型可以和返回类型不一样
第一步 创建类:让这个类作为工厂bean,实现接口FactoryBean
第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型
/** * @author ajin * @create 2022-10-05 14:21 */ public class MyBean implements FactoryBean<Course> { //定义返回bean @Override public Course getObject() throws Exception { Course course = new Course(); course.setCname("abc"); return course; } @Override public Class<?> getObjectType() { return null; } public boolean isSingleton() { return false; } }
<bean id="myBean" class="com.ajin.spring5.collectiontype.factorybean.MyBean"> </bean> @Test public void test3(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Course course = context.getBean("myBean", Course.class); System.out.println("course = " + course); }
IOC操作bean管理(bean作用域)
1、在Spring里面,设置创建bean实例是单实例还是多实例
2、在Spring里面,默认情况下,bean是单实例对象
3、如何设置单实例还是多实例
(1)在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
(2)scope属性值
第一个值 默认值,singleton,表示单实例对象
第二个值 prototype ,表示是多实例对象
<!-- 2 提取list集合类型属性注入使用 --> <bean id="book" class="com.ajin.spring5.collectiontype.Book" scope="prototype"> <property name="list" ref="bookList"></property> </bean>
(3)singleton 和 prototype区别
第一singleton 单实例,prototype 多实例
第二 设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象
设置scope值是 prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象
IOC操作Bean管理(bean生命周期)
1、生命周期
(1)从对象创建到对象销毁的过程
2、bean生命周期
(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和其他bean引用(调用set方法)
(3)调用bean的初始化的方法(需要进行配置初始化的方法)
(4)bean可以使用了(对象获取到了)
(5)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)
3、演示bean生命周期
/** bean生命周期 * @author ajin * @create 2022-10-06 0:11 */ 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="order" class="com.ajin.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod"> <property name="oname" value="手机"></property> </bean>
@Test public void testBean3(){ // ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Orders orders = context.getBean("order", Orders.class); System.out.println("第四步 获取创建bean实例"); System.out.println("orders = " + orders); //手动让bean实例销毁 // ((ClassPathXmlApplicationContext) context).close(); context.close(); }
4、bean的后置处理器,bean生命周期有七步
(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和其他bean引用(调用set方法)
(3)把bean实例传递bean后置处理器的方法postProcessBeforeInitialization
(4)调用bean的初始化的方法(需要进行配置初始化的方法)
(5)把bean实例传递bean后置处理器的方法postProcessAfterInitialization
(6)bean可以使用了(对象获取到了)
(7)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)
5、演示添加后置处理器效果
(1)创建类,实现接口 BeanPostProcessor,创建后置处理器
/** * @author ajin * @create 2022-10-06 0:31 */ 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="myBeanPost" class="com.ajin.spring5.bean.MyBeanPost"></bean> 第一步 执行无参数构造创建bean实例 第二步 调用set方法设置属性值 在初始化之前执行的方法 第三步 执行初始化的方法 在初始化之后执行的方法 第四步 获取创建bean实例 orders = com.ajin.spring5.bean.Orders@18bf3d14 第五步 执行销毁的方法
IOC操作Bean管理(xml自动装配)
1、什么是自动装配
(1)根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
2、演示自动装配过程
(1)根据属性名称自动注入
<!--实现自动装配 bean标签属性autowire,配置自动装配 autowire属性常用两个值: byName根据属性名称注入,注入值bean的id值和类属性名称一样 byType根据属性类型注入 --> <bean id="emp" class="com.ajin.spring5.autowire.Emp" autowire="byName"> <!-- <property name="dept" ref="dept"></property>--> </bean> <bean id="dept" class="com.ajin.spring5.autowire.Dept"></bean>
(2)根据属性类型自动注入
<!--实现自动装配 bean标签属性autowire,配置自动装配 autowire属性常用两个值: byName根据属性名称注入,注入值bean的id值和类属性名称一样 byType根据属性类型注入 --> <bean id="emp" class="com.ajin.spring5.autowire.Emp" autowire="byType"> <!-- <property name="dept" ref="dept"></property>--> </bean> <bean id="dept" class="com.ajin.spring5.autowire.Dept"></bean>
IOC操作Bean管理(外部属性文件)
1、直接配置数据库信息
(1)配置德鲁伊连接池
(2)引入德鲁伊连接池依赖jar包
<!--直接配置连接池--> <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="root"></property> </bean>-->
2、引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties格式文件,写数据库信息
(2)把外部properties属性文件引入到spring配置文件中
*引入 context名称空间
<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:util="http://www.springframework.org/schema/util" 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/util http://www.springframework.org/schema/util/spring-util.xsd 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>
IOC操作Bean管理(基于注解方式)
1、什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化xml配置
2、Spring针对Bean管理中创建对象提供注解
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
*上面四个注解功能是一样的,都可以用来创建bean实例
3、基于注解方式实现对象创建
第一步 引入依赖
第二步 开启组件扫描
<!--开启组件扫描 1、如果扫描多个包,多个包使用逗号隔开 2、扫描包上层目录 --> <context:component-scan base-package="com.ajin"></context:component-scan>
第三步 创建类,在类上面添加创建对象注解
//在注解里面value属性值可以省略不写, //默认值是类名称,首字母小写 //UserService -- userService //@Component(value = "userService") //<bean id="userService" class=".."/> public class UserService { public void add(){ System.out.println("service add...."); } }
4、开启组件扫描
<!--示例1 use-default-filters="false" 表示现在不使用默认filter,自己配置filter context:include-filter,设置扫描哪些内容 --> <context:component-scan base-package="com.ajin" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan> <!--示例2 下面配置扫描包所有内容 context:exclude-filter: 设置哪些内容不进行扫描 --> <context:component-scan base-package="com.ajin"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
5、基于注解方式实现属性注入
(1)@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...."); userDao.add(); } }
(2)@Qualifier:根据属性名称进行注入
这个@Qualifier注解的使用,和上面@Autowired一起使用
//定义dao类型属性 //不需要添加set方法 //添加注入属性注解 @Autowired //根据类型进行注入 @Qualifier(value = "userDaompl1")//根据名称进行注入 private UserDao userDao;
(3)@Resource:可以根据类型注入,可以根据名称注入
// @Resource //根据类型进行注入 @Resource(name = "userDaompl1") private UserDao userDao;
(5)@Value:注入普通类型属性
@Value(value = "abc") private String name;
6、完全注解开发
(1)创建配置类,替代xml配置文件
@Configuration //作为配置类,替代xml配置文件 @ComponentScan(basePackages = {"com.ajin"}) public class SpringConfig { }
(2)编写测试类
@Test public void testService2(){ ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); }
3.Aop
1、什么是Aop
(1)面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
(3)使用登录例子说明AOP
AOP(底层原理)
AOP(JDK动态代理)
1、使用JDK动态代理,使用Proxy类里面的方法创建代理对象
(1)调用newProxyInstance方法
方法有三个参数:
第一参数:类加载器
第二参数:增强方法所在的类,这个类实现的接口
第三参数:实现这个接口InvocationHandler,创建代理对象,写增强的部分
2、编写JDK动态代理代码
(1)创建接口,定义方法
public interface UserDao{
public int add(int a,int b);
public String update(String id);
}
(2)创建接口实现类,实现方法
public class UserDaoImpl implements UserDao { @Override public int add(int a, int b) { System.out.println("add方法执行了..."); return a+b; } @Override public String update(String id) { System.out.println("update方法执行了...."); return id; } }
(3)使用Proxy类创建接口代理对象
public class JDKProxy { public static void main(String[] args) { //创建接口实现类代理对象 Class[] interfaces = {UserDao.class}; // Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() { // @Override // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // return null; // } // }); UserDao userDao = new UserDaoImpl(); UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int result = dao.add(10, 20); System.out.println("result:"+result); } } //创建代理对象代码 class UserDaoProxy implements InvocationHandler{ 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; } }
AOP(术语)
1、连接点:类里面有哪些方法可以被增强,这些方法称为连接点
2、切入点:实际被真正增强的方法,称为切入点
3、通知(增强)
(1)实际增强的逻辑部分称为通知(增强)
(2)通知有多种类型
* 前置通知
* 后置通知
* 环绕通知
* 异常通知
* 最终通知
4、切面:是动作
(1)把通知应用到切入点过程
AOP操作(准备工作)
1、Spring框架一般都是基于 AspectJ 实现 AOP 操作
(1)AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作
2、基于AspectJ实现AOP操作
(1)基于xml配置文件实现
(2)基于注解方式实现(开发中一般使用注解方式使用)
3、在项目工程里引入AOP相关依赖
4、切入点表达式
(1)切入点表达式作用:知道对哪个 类里面的哪个方法进行增强
(2)语法结构:execution([权限修饰符] [返回值类型] [类全路径].[方法名称]([参数类表])
// *可以代表全部
举例1:对 com.ajin.dao.BookDao 类里面的add进行增强
execution(* com.ajin.dao.BookDao.add(..))
举例2:对 com.ajin.dao.BookDao 类里面的所有的方法进行增强
execution(* com.ajin.dao.BookDao.*(..))
举例3: 对com.ajin.dao包中里面所有类,类里面所有方法进行增强
execution(* com.ajin.dao.*.*(..))
AOP操作(AspectJ注解)
1、创建类,在类里面定义方法
public class User{
public void add(){
System.out.println("add....")
}
}
2、创建增强类(编写增强逻辑)
(1)在增强类里面,创建方法,让不同方法代表不同通知类型
//增强的类
public class UserProxy {
public void before() {//前置通知
System.out.println("before......");
}
}
3、进行通知的配置
(1)在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" 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.ajin.spring5.aopanno"></context:component-scan> (2)使用注解创建User 和 UserProxy 对象
//被增强的累
@Component
public class User{}
//增强的类
@component
public class UserProxy{}
(3)在增强类上面添加注解@Aspect
//增强的类
@component
@Aspect //生成代理对象
public class UserProxy{}
(4)在spring配置文件中开启代理对象
<!--开启Aspect生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
4、配置不同类型的通知
(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
(2)相同切入点抽取:
@Pointcut(value = "execution(* com.ajin.spring5.aopanno.User.add())") public void pointdemo(){}
(3)有多个增强类多同一个方法进行增强,设置增强类优先级 (1)在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高
@Component @Aspect //生成代理对象 @Order(3) public class UserProxy { //相同的切入点抽取 @Pointcut(value = "execution(* com.ajin.spring5.aopanno.User.add())") public void pointdemo(){ } //前置通知 //@Before注解表示作为前置通知 @Before(value = "pointdemo()") public void before(){ System.out.println("before...."); } //后置通知(返回通知) @AfterReturning("pointdemo()") public void afterReturning(){ System.out.println("afterReturning....."); } //最终通知 @After("execution(* com.ajin.spring5.aopanno.User.add())") public void after(){ System.out.println("after...."); } //异常通知 @AfterThrowing("execution(* com.ajin.spring5.aopanno.User.add())") public void afterThrowing(){ System.out.println("afterThrowing....."); } //环绕通知 @Around("execution(* com.ajin.spring5.aopanno.User.add())") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕之前...."); //被增强方法执行 proceedingJoinPoint.proceed(); System.out.println("环绕之后....."); } }
5、完全使用注解开发 (1)创建配置类,不需要创建 xml 配置文件 @Configuration @ComponentScan(basePackages = {"com.atguigu"}) @EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAop { }
AOP操作(AspectJ配置文件)
1、创建两个类,增强类和被增强类,创建方法
2、在 spring 配置文件中创建两个类对象
<!--创建对象--> <bean id="book" class="com.ajin.spring5.aopxml.Book"></bean> <bean id="bookProxy" class="com.ajin.spring5.aopxml.BookProxy"></bean>
3、在 spring 配置文件中配置切入点
<!--配置aop增强--> <aop:config> <!--切入点--> <aop:pointcut id="p" expression="execution(* com.ajin.spring5.aopxml.Book.buy(..))"/> <!--配置切面--> <aop:aspect ref="bookProxy"> <!--增强作业在具体的方法上--> <aop:before method="before" pointcut-ref="p"/> </aop:aspect> </aop:config>
4.JdbcTemplate
JdbcTemplate(概念和准备)
1、什么是 JdbcTemplate (1)Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
2、准备工作 (1)引入相关 jar 包