Spring框架
1 什么是Spring
Spring是分层的Java SE//EE应用 full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核。提供了展现层SpringMVC和持久层Spring JDBCTemplate以及业务层事务管理等众多的企业级应用技术。还能整合开源的第三方框架和类库。
2 Spring的优势
1.方便解耦,简化开发
2.AOP编程的支持
3.声明式事务的支持
4.方便程序的测试
3 Spring框架核心jar包
1.spring-aop 注解包
2.spring-beans bean
3.spring-context 上下文
4.spring-core 核心
5.spring-expressiom 表达式 spEL表达式
6.spring-jcl 日志包
4 IOC
控制反转,把创建对象的权利交给框架,是框架的重要特征。是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。最常见的方式是依赖注入(Dependency Injection ,简称DI)。还有一种方式叫依赖查找(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它,也可以说依赖被注入到对象中。
ioc的作用:
消减计算机程序代码之间的耦合
5 Spring配置文件
1.Bean标签基本配置
作用:
用于配置对象交给Spring来创建,默认是以无参构造方法来创建
基本属性:
id:给对象在容器中提供一个唯一标识
class:指定类的权限定类名,用于反射创建对象。
scope:指定对象的作用范围
singleton:单例的,默认
prototype:多例的
reques:在WEB项目中,Spring创建一个bean对象,存放在request域中
session:在WEB项目中,Spring创建一个bean对象,存放在session域中
global-session:作用在集群环境会话范围,当不是集群环境时就相当于session
2.Bean标签范围和生命周期
当scope的取值是singleton时:单例对象
一个应用只有一个对象的实例。作用范围是整个引用
生命周期:
当应用加载,创建容器时。对象被创建
只要容器在,对象一直活着
当应用卸载,销毁容器时,对象就被销毁了
当scope的取值是prototype时:单例对象
每次访问对象时,都会重新创建对象实例
生命周期:
当使用对象时,创建新的对象实例
只要对象在使用中,就一直活着
当对象长时间不使用时,被java垃圾回收器回收了
3、Bean生命周期
对象从创建到销毁的过程
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
4、Bean实例化三种方式
1.使用无参构造方法实例化
2.工厂静态方法实例化
3.工厂实例方法实例化
默认的是无参构造方法。适用于带有无参构造方法的类
工厂方式一般适用于导入第三方jar包的类
5、Bean依赖注入概念
依赖注入:是Spring框架的核心IOC的具体实现。
在编写程序时,通过控制反转,将对象的创建交给spring。但还是会有依赖关系
IOC解耦只是降低他们之间的耦合度。不会消除
依赖注入:
IOC的作用:降低程序间的耦合,不能完全消除
依赖关系的管理:交给spring管理。
当前类需要使用其它类对象的时候,由spring提供,我们只需要配置文件中说明即可
6、依赖注入的方法
1.构造方法
2.set方法
6 Spring配置数据源
配置druid数据源,需要导入的jar包有:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
配置druid数据源,基于配置文件的方法。用spEL的方法调用配置文件中的值
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.drive}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
7 Spring的AOP
1、AOP简介:
AOP(Aspect Oriented Programming) ,意思是面向切面编程,使用过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP是OOP的延续,是软件开发的一个热点,也是Spring框架的一个重要内容,是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑个部分之间的耦合度降低。提高程序的可重用性。提高开发的效率。便于维护
简单地说就是把程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强
2、AOP的作用及优势
作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
优势:减少代码的重复,提高开发效率,便于维护
3、AOP底层实现
AOP底层是通过Spring提供的动态代理技术实现的,在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强
4、AOP的动态代理技术
常用的动态代理技术
JDK代理:基于接口的动态代理技术
cglib代理:基于父类的动态代理技术
5、AOP的相关概念
Spring的AOP实现低=底层就是对上面的动态代理的代码进行了封装封装后我们只需要对需要关注的部分进行代码的编写。再通过配置的方式完成制定目标的方法增强。
AOP常用的术语:
Target(目标对象):代理的目标对象
Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点 (可以被增强的方法)
Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义 (已经被增强方法)
Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知 (需要执行代码)
Aspect(切面):是切入点和通知(引介)的结合
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入
注意: 所有的切入点都是连接点,但是连接点不一定是切入点
6、基于XML的AOP开发
步骤:
-
导入AOP相关坐标
<!--导入spring的context坐标,context依赖aop--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- aspectj的织入 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version>
2.创建目标接口和目标类(内部有切点)
public interface TargetInterface {
public void method();
}
public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}
3.创剪切面类(内部有增强方法)
public class MyAspect {
//前置增强方法
public void before(){
System.out.println("前置代码增强.....");
}
}
4.在配置文件中配置织入关系
4.1导入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/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
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
4.2配置切点表达式和前置增强的织入关系
<aop:config>
<!--引用myAspect的Bean为切面对象-->
<aop:aspect ref="myAspect">
<!--配置Target的method方法执行时要进行myAspect的before方法前置增强-->
<aop:before method="before" pointcut="execution(public void com.itheima.aop.Target.method())"></aop:before>
</aop:aspect>
</aop:config>
7、XML配置AOP详解
1.切点表达式的写法
表达式语法:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
修饰符可以省略
返回值类型、包名、类名、方法名可以用星号*代表任意
包名和类名之间的一个点.代表当前包下的类。 两个点..表示当前包及其子包下的类
参数列表可以使用两个点..表示任意个数、任意类型的参数列表
切点表达式可以进行抽取
<aop:pointcut id=“id” expression = “execution()”/>
可以用pointcut-ref="id"来引用切点表达式
<aop:config>
<!--引用myAspect的Bean为切面对象-->
<aop:aspect ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.itheima.aop.*.*(..))"/>
<aop:before method="before" pointcut-ref="myPointcut"></aop:before>
</aop:aspect>
</aop:config>
2.通知类型
通知的配置语法:
<aop:通知类型 method=“切面类中方法名” pointcut=“切点表达式"></aop:通知类型>
名称 | 标签 | 说明 |
---|---|---|
前置通知 | <aop:before> | 用于配置前置通知。指定增强的方法在切入点方法执行之前执行 |
后置通知 | <aop:after-returning> | 用于配置后置通知。指定增强的方法在切入点方法执行之后执行 |
环绕通知 | <aop:around> | 用于配置环绕通知。指定增强的方法在切入点方法执行之前和之后都执行 |
异常抛出通知 | <aop:throwing> | 用于配置异常抛出通知。指定增强的方法在出现异常的时候执行 |
最终通知 | <aop:after> | 用于配置最终通知。无论增强方式执行是否有异常都会执行 |
注:后置通知和异常通知,只能执行其中一个
XML配置方式:“最终通知”,需要写在其他通知的后面,否则他会在“后置”或“异常抛出通知”前执行
3.aop织入的配置
<aop:config>
<aop:aspect ref=“切面类”>
<aop:通知类型 method=“通知方法名称” pointcut=“切点表达式"></aop:before>
</aop:aspect>
</aop:config>
8.基于注解的AOP开发
步骤:
1.创建目标接口和目标类(内部有切点)
public interface TargetInterface {
public void method();
}
public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}
2.创建切面类(内部有增强方法)
public class MyAspect {
//前置增强方法
public void before(){
System.out.println("前置代码增强.....");
}
}
3.将目标类和切面类的对象创建权交给 spring
@Component("target")
public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}
@Component("myAspect")
public class MyAspect {
public void before(){
System.out.println("前置代码增强.....");
}
}
4.在切面类中使用注解配置织入关系
@Component("myAspect")
@Aspect
public class MyAspect {
@Before("execution(* com.itheima.aop.*.*(..))")
public void before(){
System.out.println("前置代码增强.....");
}
}
5.在配置文件中开启组件扫描和 AOP 的自动代理
<!--组件扫描-->
<context:component-scan base-package="com.itheima.aop"/>
<!--aop的自动代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
9、注解配置AOP详解
1.注解通知的类型
通知的配置语法:@通知注解(“切点表达式”)
名称 | 标签 | 说明 |
---|---|---|
前置通知 | @Before | 用于配置前置通知。指定增强的方法在切入点方法执行之前执行 |
后置通知 | @AfterReturning | 用于配置后置通知。指定增强的方法在切入点方法执行之后执行 |
环绕通知 | @Around | 用于配置环绕通知。指定增强的方法在切入点方法执行之前和之后都执行 |
异常抛出通知 | @After Throwing | 用于配置异常抛出通知。指定增强的方法在出现异常的时候执行 |
最终通知 | @After | 用于配置最终通知。无论增强方式执行是否有异常都会执行 |
2.切点表达式的抽取
@Pointcut("execution(* com.itheima.aop.*.*(..))")
public void myPoint(){}
}