spring构建步骤(eclipse)
1. spring框架:最基础的4个包:(以下是通过配置文件方式)
https://www.bilibili.com/video/BV1UE411A7A6?p=5&spm_id_from=pageDriver&vd_source=e9350dcb8f8ce540f675f37bddfce935
1.spring-core
2.spring-beans
3.spring-context
4.spring-expression
2.核心配置文件
在main下面建立resources,java目录和resources是同一级目录
用来进行bean的配置,文件名可以自定义,一般默认为applicationContext.xml
applicationContext.xml这个配置文件里面配置了bean的信息,这样容器就能知道bean信息,才能帮我们创建了.
<bean id="helloSpring" class="com.yyp.Hello">
配置文件:
<?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="helloSpring" class="com.yyp.Hello">
//值的注入是通过setName()方法进行注入的,也叫做数据装配
<property name="name" value="tom"></property>
</bean>
</beans>
3.读取spring的上下文
//获取Ioc容器,读取配置文件,初始化spring上下文
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//根据id获取容器中的bean
Hello hello = (Hello) ac.getBean("helloSpring");
hello.show();
System.out.println(hello.getName());
五.两种类型的Ioc容器的类型
1.ApplicationContext
继承路径:ApplicationContext---->ApplicationEventPublishe--->EnvironmentCapable---->HierarchicalBeanFactory---->BeanFactory
ClassPathXMLApplicationContext
FileSystemXmlApplicationContext
代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = (Hello) ac.getBean("helloSpring");//表示Ioc容器
hello.show();
System.out.println(hello.getName());
ApplicationContext ac2= new FileSystemXmlApplicationContext("d:/applicationContext.xml");
Hello hello2 = (Hello)ac2.getBean("helloSpring");
hello2.show();
System.out.println("从硬盘获取:"+hello2.getName());
2.BeanFactory
XmlBeanFactory已过时
代码:
ClassPathResource resource = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resource);//表示Ioc容器
Hello hello3 = (Hello) bf.getBean("helloSpring");
System.out.println("BeanFactory:" + hello3.getName());
六.数据装配
1.简介
为bean中的属性注入值,称为数据的装配,可装配不同类型的值
*简单类型(共19种)------->value="值"
八种基本类型以及包装类:byte short long float double char boolean
Byte Short Integer Long Float Double Character Boolean
String Class Resource
*引用类型的注入:---------->ref
xml配置:
<beans>
<bean id= "otherBean" class="ioc5.OtherBean">
<property name="name" value="jack">
</bean>
<bean id="springrBean" class="ioc5.SpringBean">
<property name="otherBean" ref="otherBean">
</bean>
</beans>
*集合装配:---
数组,LIst,Set,Map,Properties
*数组装配配置:
<bean id="springBean" calss="ioc05.SpringBean">
<property name="otherBean" ref="otherBean">
<property name="arrays成员便利名字">
<array>
<value>1</value>//数组里面存放的是基本数据类型
<value>2</value>
<value>3</value>
</array>
</property>
<property name="lists成员变量名字">//给list进行注入
<list>
<ref bean="otherBean"/>//列表里面装的是另外一种引用类型,这种注入是引用外边已经定义好的bean到这里
<ref bean="otherBean"/>//这个和上面的是同一个otherBean对象
<bean class="ioc5.OtherBean">//这里直接是创建一个bean,注入到list里面
<property name="name" value="zhangsan"/>
</bean>
<bean class="ioc5.OtherBean">//这里直接是创建一个bean,注入到list里面
<property name="name" value="lisi"/>
</bean>
</list>
</property>
<property name="sets成员变量名字">//给set进行注入
<set>
<ref bean="otherBean"/>//set里面装的是另外一种引用类型,这种注入是引用外边已经定义好的bean到这里
<ref bean="otherBean"/>//这个和上面的是同一个otherBean对象
<bean class="ioc5.OtherBean">//这里直接是创建一个bean,注入到list里面
<property name="name" value="zhangsan"/>
</bean>
<bean class="ioc5.OtherBean">//这里直接是创建一个bean,注入到list里面
<property name="name" value="lisi"/>
</bean>
</set>
</property>
<property name="map成员变量">
<map>
<entry key-reg="otherBean" value="java.lang.Integer"/>
</mpa>
</property>
</bean>
*装配null类型
<bean id="springBean"- class="ioc6.SpringBean">
<property name="name">
<null/>
</property>
</bean>
七.bean的生命周期
1.生命周期:
代码块--->实例化(构造方法)----->数据装配--->初始化方法(init()对装配完成的数据进行处理))------->bean准备就绪--->使用-->从容器销毁
2.初始化方法/销毁方法
public void init(){
this.name=this.name.toUpperCase(+"_"+this.sectoUpperCase())
}
xml装配配置:
<bena id="springBean" calss="ioc07.SpringBean" init-method="init" destroy-methdod="destroy">
<property name="name" value="alice">
<property name="sex" value="female">
</bean>
实例化的方式:
1.构造方式:无参,有参,new
2.静态工厂:无参,有参,静态方法
3.实例工程:无参,有参(非静态方法)
构造方法:
1.通过无参构造方法注入:
<bean id="springBean2" class="ioc09.SpringBean">
<property name="name" value="alice"/>
<property name="pwd" value="456"/>
<property name="age" value="21"/>
</bean>
2.通过有参构造方法注入:
<bean id="springBean2" class="ioc09.SpringBean">
<constructor-arg name="name" value="alice"/>
<constructor-arg name="pwd" value="456"/>
<constructor-arg name="age" value="18"/>
</bean>
静态方法:
通过静态方法(无参静态方法)进行装配
<bean id="springBean" class="ioc10.SpringBeanFactory" factory-method="getSpringBean">
<property name="name" value="jack">
</bean>
通过静态方法(带参的静态方法)进行装配:
<bean id="springBean2" class="ioc10.SpringBeanFactory" factory-method="getSpringBean">
<constructor-arg name="name" value="lucy"/>
</bean>
通过Ioc容器拿到Calendar的实例
<bean id="calendar" class="java.util.Calendar" factory-method="getInstance"/>
通过Ioc容器获取系统环境信息(无参)
<bean id="envs" class="java.lang.System" factory-method="getenv"/>
通过Ioc容器获取系统环境信息(有参)
<bean id="javaHome" class="java.lang.System" factory-method="getenv">
<constructor-arg name="name" value="JAVA_HOME/">
</bean>
4.实例工厂
通过工厂类的实例调用它的实例方法来获取对象
1.首先配置实例工厂类的,让Ioc容器自动创建工厂对象
2.通过工厂对象调用它的实例方法来创建对象
<bean id="springBeanFactory" class="ioc12.SpringBeanFactory"/>//这个就是上面的第一个步骤
<bean id="springBean" factory-bean="SpringBeanFactory" factory-method="getSpringBean">/这个就是上面的第二个步骤
<property name="name" value="tom"/>
</bean>
采用带参的工厂方法:
<bean id="springBean" factory-bean="springBeanFactory" factory-method="getSpringBean">
<constructor-arg name="name" value="alice"/>
</bean>
二.Bean实例化的时机
1.ApplicationContext容器
默认预先实例化,即在容器启动时就实例化了,可以设置为懒实例化,通过这个lazy-init="true"可以修改实例化的时机,就是在第一次使用 的时候再进行实例化.
<bean id="springBean" class="ioc4.SpringBean" lazy-init="true">
<property name="name" value="alice">
</bean>
实际应用中都是预先实例化,虽然启动时较慢,但是用户访问时速度较快,一般测试的时候用懒实例化
2.BeanFactory容器
只能懒实例化,使用bean时才会实例化
三.Bean作用域
1.简洁
在Ioc容器中bean默认是单例的,存在的问题
单例的bean的属性时线程不安全的,多线程并发访问时数据不安全
设置scope属性来指定作用域,配置为非单例的,scope默认值为singleton
下面这个是默认的情况,也就是单例模式
<bean id="springBean" class="ioc15.SpringBean" scope="singleton">
<property name="name" value="alice">
</bean>
下面这个是修改了scope的作用域,也就是多例模式
<bean id="springBean" class="ioc15.SpringBean" scope="prototype">
<property name="name" value="alice">
</bean>
2.用法 scope作用域:取值
singleton:单例
prototype:多例
request.同一个请求中是单例,如果不是同一个请求就是多例
session:同一个会话中是单例(同一个浏览器),如果是不同的浏览器就是多例
四:继承配置(是xml配置文件里面的配置之间的继承关系和类的继承没有关系)
1.简介
用来简化代码,减少配置
1.继承配置.下面是把password放到父类配置里面
<bean id="Parent" abstract="true">
<property name="password" value="123"/>
</bean>
<bean id="springBean" class="ioc16.SpringBean" parent="Parent">
<property name="name" value="admin"/>
<property name="age" value="18"/>
</bean>
<bean id="otherBean" class="ioc16.OtherBean" parent="Parent">
<property name="name" value="alice"/>
<property name="sex" value="female"/>
</bean>
2.还可以把class放到父配置里面
<bean id="parent2" class="ioc16.SpringBean" abstract="true">
<property name="password" value="123"/>
</bean>
<bean id="bean1" parent="parent2">
<property name="name" value="zhangsan"/>
<property name="age" value="26">
</bean>
<bean id="bean2" parent="parent2">
<property name="name" value="lisi"/>
<property name="age" value="16">
</bean>
小结:
用法1:不同的子bean类继承自父bean
用法2:相同的子bean类继承自父bean
五.自动装配
1.简介
Ioc容器可以根据bean 的名称,类型或构建方法自动进行注入,称为自动装配
只针对其他的bean的引用
2.配置方式(以上的例子都是手动装配)
下面的是自动装配
autowire:取值
default:不进行自动装配,等同于no
byName:根据说下名进自动装配,根据说下名字查找同名的bean,如果能找到就装配成功,如果找不到就装配失败
byType:(工作常用过的)根据属性类型自动装配.查找同类型的bean,如果能找到就装配成功.如果找不到就装配失败,如果查找到多个bean,那么就会装配失败,因为bean不唯一
constructor:根据构造方法进行自动装配,同时根据byName和byType进行自动装配,先按照byName,再按照byType进行自动装配,注意:此时不是通过setter方法进行装配的,所以可以不写对应的setter方法
<bean id="springBean" class="loc17.SpringBean" autowire="constructor">
</bean>
<bean id="otherBean" class="ioc17.SpringBean">
<property name="name" value="tom"/>
</bean>
六.在Bean中获取Ioc容器
1定义一个Ioc容器的工具类
步骤:
1.定义一个类,实现ApplicationContextAutoware接口
2.将工具bean添加到Ioc容器
3.调用工具类,获取Ioc容器中的bean
七.FactoryBean
1.简介
Spring中有两种类型的Bean
*普通Bean:返回的是Bean本身的对象
*工厂Bean:即FactoryBean,返回的并不是它本身的对象
应用场合:如果普通bean的配置比较复杂,在配置文件中定义时不走比较多,此时可以使用FactoryBean
2.定义FactoryBean
步骤:
1.定义一个类,实现FactoryBean接口
2.将该bean添加到Ioc容器容中
3.从容器中获取该bean
八.Resources类
1.简介:
本质就是对java.io.File的封装
根据资源位置不同,提供了不同的实现类,用来快速获取文件资源
*FileSystemResources
*ClassPathResources
*UrlResources
*InputStreamResource
2.基本用法
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
Resource resource = new ClassPathResource("applicationContext.xml");
InputStream inputStream = resource.getInputStream();
StreamUtils.copy(inputStream, new FileOutputStream("d:/1.xml"));
3.自动装配注入Resource
<bean id="springBean" class="ioc21.SpringBean">
//下面这个是注入的是文件系统路径下的
<property name="resource" value="file:d:/1.xml"/>
//如果是类路径下的
<property name="eresource" value="class:applicationContext.xml"/>
</bean>
九.后()置)处理器
1.两种后处理器
*Bean后处理器,实现BeanPostPressor接口
*BeanFactory后处理器,实现BeanFactoryProcessor接口,也称为容器后处理器
2.BeanPostProcessor
2.1简介
Bean后处理器用来对bean的功能进行扩展增强,对Ioc容器中的所有bean都有效
时机:执行初始化方法之前后之后
代码块---->实例化---->数据装配---->初始化之前---->初始化方法---->初始化之后--->就绪---->使用------>销毁方法--->从容器中销毁
2.2实现步骤:
1.定义一个类,实现BeanPostProcessor接口
2.将该后处理器添加到Ioc容器中
<bean class="ioc22.SpringBeanPostProcessor"/>
3.BeanFactoryPostProcessor
3.1简介
容器后处理器在bean创建之前,修改bean的定义属性
bean的生命周期:
BeanFactoryPostProcessor---->代码块---->实例化---->数据装配---->初始化之前---->初始化方法---->初始化之后--->就绪---->使用------>销毁方法--->从容器中销毁
3.2实现步骤:
1.定义一个类,实现BeanFactoryPostProcessor
2.将该bean添加到Ioc容器中
<bean class="ioc24.SpringFactoryPostProcessor"/>
3.定义属性编辑器PropertyEditor(转换器),实现PropertyEditor接口或者继承PropertyEditoSupport父类
4.在容器后处理器中注册属性编辑器
//向容器中注册属性编辑器,第一个参数表示要转换的类型,第二个参数表示要使用的属性编辑器
beanFactory.registerCustomEditor(Address,AddressEditor.class);
3.4内置容器后处理器
Spring预定定义了容器后处理器
*CustomEditorConfigurer:用来注册自定义的属性编辑器
<bean class="org.springframework.beans.factory.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="ioc24.Address" value="ioc24.editor.AddressEditor">
<entry key="java.util.Date" value="ioc24.editor.DateEditor">
<entry key="java.lang.String" value="ioc24.editor.StringEditor">
<entry key="java.lang.Boolean" value="ioc24.editor.BooleanEditor">
</map>
</bean>
*PropertyPlaceholderConfigurer:用来读取属性文件,同时内置了常用的属性编辑器
AOP:面向切面编程,作为oop的一种补充
1.1将程序中交叉业务逻辑(事务,日志,)代码提取出来,封装成切面,由AOP容器在适当的时机(位置)将封装的切面动态的植入到具体业务逻辑中.
AOP不是Spring特有的
1.2.应用场合
适用于具有横切逻辑的场合,如事务管理,日志记录,性能监测,异常通知,访问控制等,都适用的AOP
1.3作用
*不改变原有代码的基础上动态添加欣的功能
*可以模块化,方便维护
1.4术语
*连接点Joinpoint
程序执行的某个特定位置,如方法调用前,方法调用后,方法抛出异常时,方法调用前后等
*切入点Pointcut
定位查找到需要的连接点,即切点
*增强Advice也称为通知
在切点执行的一段程序代码,用来实现某些功能,
*目标对象Target
将执行增强处理的类称为目标对象
*织入Weaving
将增强添加到目标类的具体切入点上的过程
*代理Proxy
一个类被织入增强后,会产生一个代理类
*切面Aspect
切点和增强的组合就叫做切面
*引介(Introduction)也称为引入
2.实现原理
2.1回顾:代理模式
概念:为其他对象提供一种代理,以控制对这个对象的访问,起到中介的作用
通过代理对象访问目标对象,可以增强额外的操作,扩展目标对象的功能
分类:
*静态代理
代理类是程序员自己创建或工具生成
所谓静态就是程序运行之前就已经存在代理类的字节码文件
缺点:代理对象需要和目标对象实现相同的接口,如果接口增加方法,目标对象和代理对象都需要维护
*动态代理
代理类是程序运行期间由JVM根据反射等机制生成的代理类,自动生成代理类和代理对象
所谓动态就是在程序运行期不存在代理类的字节码文件
代理三要素:
1.目标类接口
2.目标类的实例
3.交叉业务逻辑,就是你要执行的操作
动态代理2种实现技术:
1.jdk技术
Proxy.newProxyInstance(
classload/,//目标类的类加载器
interface,//目标类的接口列表
InvocationHandler,//交叉业务逻辑
)
代码:
public static void main(String[] args){
UserService userService=(UserService) Proxy.newProxyInstance(
UserServiceImpl.class.getClassLoader(),//目标类的类加载器
new Class[]{UserService.class}.//目标类的接口列表
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
//1.打印日志
System.out.println(method.getName()+"login at["+new Date(.getTime(+"]")));
Object returnValue=method.invoke(new UserServiceImpl(),args):
}
);
}
特点:目标对象必须实现一个或多个接口,如果么有实现任何接口,则无法使用jdk的动态代理,此时可以使用cglib技术
2.cdlib技术
使用于无接口时使用
2.2cglib技术
如果没有实现接口,则通过继承来实现的
步骤:
1.添加jar包 cglib-3.3.0.jar,asm-7.1.jar(依赖的jar包)
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2.用法
代码:
public static void main(String[] args) {
Object helloWorld = Enhancer.create(HelloWorld.class, // 目标类的类型
new InvocationHandler() {// 这个是交叉业务
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + "这个方法执行开始了" + new Date().toLocaleString());
Object returnValue = method.invoke(new HelloWorld(), args);
System.out.println(method.getName() + "这个方法执结束了" + new Date().toLocaleString());
return returnValue;
}
});
((HelloWorld) helloWorld).sayHello();// 也可以在创建HelloWorld对象的时候进行强制转换
}
2.3AOP配置
Spring AOP原理就是使用动态代理
*对于实现了接口的目标类,使用的是jdk动态代理
*对于没有实现任何接口的目标类,使用的是cglib的动态代理
3.Spring Aop的配置方式
3.1三种配置方式
*Spring AOP 1.x.使用ProxyFactoryBean手动代理
*SpringAOP2.x,基于命名空间的配置
*Annotation,基于注解的配置值(推荐)
3.2Advice类型
Spring AOP支持5种类型的增强(通知)
增强类型 实现接口 描述
前置增强 MethodBeforeAdvice 在方法执行前添加功能
后置增强 AfterReturningAdvice 在方法执行后添加功能
环绕增强 MethodInterceptor 在方法执行前后添加功能
异常增强 ThrowsAdvice 在方法抛出异常后添加功能
引入增强 IntroductionInterceptor 在目标类中添加新方法和属性
注意:多个Advice之间不允许有耦合,即多个Advice之间不允许有业务交叉
二.Spring AOP 1.x
1.基本用法
1.1添加jar包:spring-aop和spring-aspects,cglib包
还要添加Ioc的包,这个是核心功能包:
1.spring-core
2.spring-beans
3.spring-context
4.spring-expression
总共7个jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.20</version>
</dependency>
1.2配置Advice
定义一个增强类,实现相应接口
配置目标类的实例:<bean id="userServiceTarget" class="aop04.service.impl.UserServiceImpl">
1.3配置Pointcut
定义切入点,配置位置信息,指定哪些类的哪些方法需要被执行AOP
使用NameMatchMethodPointcutAdvisor根据方法名匹配切入点
Advisor是Pointcut和Advice的配置器,Pointcut+Advice=Advisor,这个过程叫做织入
applicationContext.xml配置
<bean id="logAdvice" class="aop04.advice.LogAdvice"/>//配置Advice
//配置Advisor,将Advice注入到Pointcut位置:织入的过程
<bean id="logAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="logAdvice"/>//指定Advice
//配置Pointcut,指定匹配哪些方法
<property name="mapperdNames">
<list>
<value>login</value>
<value>logout</value>
</list>
</property>
</bean>
1.4配置代理
使用ProxyFactoryBean配置代理
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">//配置代理类
<property name="target" ref="userServiceTarget"/>//目标类的实例
<property name="interface">目标类的接口列表
<list>
<value>aop04.service.UserService</value>
</list>
</property>
<property name="interceptNames">//交叉业务逻辑
<list>
<value>logAdvisor</value>
</list>
</property>
</bean>
调试过的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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--bean信息 -->
<bean id="helloSpring" class="com.yyp.Hello">
<property name="name" value="tom"></property>
</bean>
<bean id="applicationContextHolder" class="com.yyp.ApplicationContextHolder"/>
<bean id="userServiceTarget" class="com.yyp.UserServiceImpl"/>
<!-- 配置Advice -->
<bean id="logAdvice" class="com.yyp.LogAdvice"/>
<!-- 配置Advisor,将Advice注入到Pointcut位置:织入的过程 -->
<bean id="logAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 指定advice -->
<property name="advice" ref="logAdvice"/>
<!-- 配置Pointcut,指定匹配哪些方法 -->
<property name="mappedNames">
<list>
<value>login</value>
<value>logout</value>
</list>
</property>
</bean>
<!-- //配置代理类 -->
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 目标类的实例 -->
<property name="target" ref="userServiceTarget"/>
<!-- 目标类的接口列表 -->
<property name="interfaces">
<list>
<value>com.yyp.UserService</value>
</list>
</property>
<!-- //交叉业务逻辑 -->
<property name="interceptorNames">
<list>
<value>logAdvisor</value>
</list>
</property>
</bean>
</beans>
执行结果:
class com.sun.proxy.$Proxy4表示使用的是jdk的动态代理
配置文件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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--bean信息 -->
<bean id="helloSpring" class="com.yyp.Hello">
<property name="name" value="tom"></property>
</bean>
<bean id="applicationContextHolder" class="com.yyp.ApplicationContextHolder"/>
<bean id="userServiceTarget" class="com.yyp.UserServiceImpl"/>
<bean id="goodByeAdvice" class="com.yyp.advice.GoodByeAdvice"/>
<bean id="timerAdvice" class="com.yyp.advice.TimerAdvice">
<property name="time" value="3000"/>
</bean>
<bean id="exceptionAdvice" class="com.yyp.advice.ExceptionAdvice"/>
<!-- 配置Advice -->
<bean id="logAdvice" class="com.yyp.advice.LogAdvice"/>
<!-- 配置Advisor,将Advice注入到Pointcut位置:织入的过程 -->
<bean id="logAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 指定advice -->
<property name="advice" ref="logAdvice"/>
<!-- 配置Pointcut,指定匹配哪些方法 -->
<property name="mappedNames">
<list>
<value>login</value>
<!-- <value>logout</value> -->
</list>
</property>
</bean>
<bean id="goodByeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="goodByeAdvice"/>
<property name="mappedNames">
<list>
<value>logout</value>
</list>
</property>
</bean>
<bean id="timerAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="timerAdvice"/>
<property name="mappedNames">
<list>
<value>login</value>
<value>logout</value>
</list>
</property>
</bean>
<bean id="exceptionAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="exceptionAdvice"/>
<property name="mappedNames">
<list>
<value>*</value>
<value>logout</value>
</list>
</property>
</bean>
<!-- //配置代理类 -->
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 目标类的实例 -->
<property name="target" ref="userServiceTarget"/>
<!-- 目标类的接口列表 -->
<property name="interfaces">
<list>
<value>com.yyp.UserService</value>
</list>
</property>
<!-- //交叉业务逻辑 -->
<property name="interceptorNames">
<list>
<value>logAdvisor</value>
<value>goodByeAdvisor</value>
<value>timerAdvisor</value>
<value>exceptionAdvisor</value>
</list>
</property>
</bean>
</beans>
三.Spring AOP 2.x
1.简介
基于命名的配置,员阿里是使用后处理器,更简单
特点:
*简化配置
*非侵入性,编写增强时不需要实现任何接口
*使用AspectJ表达式定义切入点
2.基本用法
2.1配置Advice
定义增强类,不需要再定义接口,但有多种写法
写法 说明
public void 方法名(Joinpoint) 前置通知
public void 方法名(Joinpoint,Object) 后置通知,Object参数用来接收目标方法的返回值得
public void 方法名(Joinpoint,Exception) 异常通知,Exception参数用来接收异常对象
public void 方法名(ProceedingJoinpoint) 环绕通知
2.2配置Pointcut切入点
四.AspectJ表达式
1.简介
切点表达式,一种表达式,用来定义切点位置
2.用法
2.1within
语法:within(包名.类名)
匹配该类中的所有方法
2.2excution
匹配特定包中的特定类中特定返回值类型的特定参数的特定方法
语法:excution{表达式}
表达式:返回值类型, 包名.类名.方法名(参数类型)
通配符:*和..
Spring注解:
一简介
Spring提供了一系列的注解来替代配置文件,简化配置
实际开发中,建议使用注解+配置的形式
二:Ioc注解
spring的pom.xml文件
<?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>com.yyp</groupId>
<artifactId>HelloSpring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HelloSpring</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.20</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>4.0.0-M1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
application.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:component-scan base-package="ioc"/>
</beans>
二.Ioc注解
1.配置扫描包
<context:component-scan base-package="ioc"/>
<context:component-scan base-package="ioc.com.yyp.dao"/>
<context:component-scan base-package="ioc.com.yyp.dao.impl"/>
<context:component-scan base-package="ioc.com.yyp.userservice.impl"/>
2.常用注解
2.1组件的定义
@Component定义Bean组件,添加类到Ioc容器中,这个注解不区分组件类型的
@Repository表示Dao组件
@Controller表示Action组件
2.2.数据装配
简单类型装配:
注解方式的数据装配是直接使用属性进行注入,不是使用setter方法,所以可以不要set和get方法
@Value("666")
private int num;
@Value("true")
private Boolean flag;
@Value("${jdbc.username}")
private String userName;
@Value("java.lang.String")
private Class clazz;
@Value("classpath:spring.xml")
private Resource resource;
读取属性文件:
<context:component-scan base-package="ioc" />
<!-- bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:info.property" />
</bean>-->
<context:property-placeholder location="classpath:info.properties"/>
其他bean的引用:
/**
* 方式一:使用@Autowired,spring提供的 自动装配,默认是按照类型Bytype进行装配,如果有多个同类型的bean,则按byName 可以结合qualifier按指定byName注入
*/
// @Autowired
// @Qualifier("ob")
@javax.annotation.Resource
集合的装配:
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 配置扫描包 -->
<context:component-scan base-package="ioc" />
<!-- bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:info.property" /> </bean> -->
<context:property-placeholder
location="classpath:info.properties" />
<bean id="ob" class="ioc.OtherBean">
<property name="msg" value="呵呵哈哈" />
</bean>
<!-- 集合类型的装配 -->
<util:list id="as">
<value>1</value>
<value>2</value>
<value>3</value>
</util:list>
<util:list id="lists">
<ref bean="ob" />
<ref bean="otherBean" />
<ref bean="otherBean" />
<bean class="ioc.OtherBean">
<property name="msg" value="嘿嘿" />
</bean>
</util:list>
<util:set id="sets">
<bean class="ioc.OtherBean">
<property name="msg" value="嘿嘿" />
</bean>
</util:set>
<util:map id="maps">
<entry key-ref="otherBean" value="java.lang.String"></entry>
</util:map>
<util:properties id="properties">
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
</util:properties>
</beans>
代码部分:
package ioc;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
//默认bean的id为类名首字母小写,如果不同包下存在同名的类,则可以修改id
@Component("sb")
public class SpringBean {
@Value("666")
private int num;
@Value("true")
private Boolean flag;
@Value("${jdbc.username}")
private String userName;
@Value("java.lang.String")
private Class clazz;
@Value("classpath:spring.xml")
private Resource resource;
/**
* 方式一:使用@Autowired,spring提供的 自动装配,默认是按照类型Bytype进行装配,如果有多个同类型的bean,则按byName 可以结合qualifier按指定byName注入
*/
// @Autowired
// @Qualifier("ob")
@javax.annotation.Resource
private OtherBean otherBean;
// 集合的装配,就是使用Resource注解,默认是按照byName进行注入
@javax.annotation.Resource(name = "as")
private Integer[] arrays;
@javax.annotation.Resource(name = "lists")
private List<OtherBean> lists;
@javax.annotation.Resource()
private Set<OtherBean> sets;
@javax.annotation.Resource
private Map<OtherBean, Class> maps;
@javax.annotation.Resource
private Properties properties;
@Override
public String toString() {
return "SpringBean [num=" + num + ", flag=" + flag + ", userName=" + userName + ", clazz=" + clazz
+ ", resource=" + resource + ", otherBean=" + otherBean + ", arrays=" + Arrays.toString(arrays)
+ ", lists=" + lists + ", sets=" + sets + ", maps=" + maps + ", properties=" + properties + "]";
}
2.3生命周期:就2个注解
// 这个就相当于init-method=""
@PostConstruct
public void init() {
System.out.println("SpringBean.init");
}
// 这个就相当于destroy-method=""
@PreDestroy
public void destroy() {
System.out.println("SpringBean.destroy");
}
2.4bean实例化的时机
@Lazy在类上面加,而且是单例的
2.5scope作用域
@Lazy懒加载
@Scope("prototype"),非单例的
三.AOP注解
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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yyp</groupId>
<artifactId>HelloSpring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HelloSpring</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.20</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>4.0.0-M1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
三AOP注解
1.配置Advice
定义增强类,添加@Compronent和@Aspect注解
2.配置Pointcut并指定通知类型
@Pointcut(切点表达式)
@Before(切点方法名())
@AfterReturning
@Around
3.织入
一Spring整合web项目
1.1基本用法
1,2.添加jar包
spring ioc的4个包:spring-core,spring-beans,spring-context,spring-expression
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.3.20</version>
</dependency>
spring-aop的3个包:spring-aop,spring-aspects,spring-cglib
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
java EE的3个包javax.servlet-api,jstl,jsp-api
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
spring-web的包:spring-web
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.21</version>
</dependency>