Spring入门
Spring是什么?
Spring是一个开源框架,为简化企业级应用开发而生。
创新互联建站是一家专业提供罗城企业网站建设,专注与成都网站设计、网站建设、外贸网站建设、H5开发、小程序制作等业务。10年已为罗城众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。
Spring是一个 IOC 和 AOP 容器框架。
Spring 是轻量级的、面向切面编程、依赖注入的一站式框架。
搭建Spring开发环境
导入
commons-logging-1.1.1.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
Bean配置
IOC & DI 概述
IOC:反转控制器,思想是反转资源获取的方向,传统资源查找方式是组件向容器发起请求查找资源,IOC 则是容器主动的将资源推送给它所管理的组件。
DI:依赖注入,组件预定义的方式接受资源注入。
Spring 容器
在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前,必须要对其进行实例化,只有实例化后,才可以从 IOC 容器中取出并使用。
Spring 提供了两种类型的 IOC:
BeanFactory:IOC 容器的基本实现。
ApplicationContext:提供了更多的特性,是 BeanFactory 的子接口,在初始化上下文阶段就实例化了所有单例Bean。
AppliactionContext 主要实现类
ClassPathXmlApplicationContext:从类路径下加载配置文件。
FileSystemXmlApplicationContext:从文件系统下加载配置文件。
ConfigurableApplicationContext:ApplicationContext 的扩展类,新增 refresh 和 close 方法,使其具有启动、刷新和关闭上下文的功能。
WebApplicationContext:Web 应用专属。
配置形式
基于 XML 方式
基于注解的方式
Spring 能从 classpath 中自动扫描、侦测和实例化具有特定注解的组件,包括:
@Component: 基本注解,标识一个受 Spring 管理的组件。
@Respository:标识持久层组件。
@Service:标识业务层组件。
@Controller:标识表现层组件。
对于扫描到的组件,Spring 有特定的命名策略,当然可以在注解中通过 value 属性指定组件名。
当在组件中使用了注解后,还需要在配置文件中声明\
base-package:扫描组件基类包,Spring 容器将扫描该包下的所有类,当需要扫描多个包时,用逗号隔开。
resource-pattern:仅扫描基类中的特定类。
use-default-filters:默认为ture,扫描@Component、@Respository、@Service、@Controller 组件。
\
\
类别 | 说明 | |
---|---|---|
annotation | com.kernel.XxxAnnotation | 所有标注了XxxAnnotation的类,该类型采用目标类是否标注了某个注解进行过滤 |
assignable | com.kernel.XxxService | 所有继承或扩展XxxService的类,该类型采用了目标类是否继承或扩展某个特定类进行过滤 |
aspectj | com.kernel.*Service | 所有类名义Service结束的类及继承或扩展它们的类,该类型采用AspectJ表达式进行过滤 |
regex | com.kernel.anno.* | 所有com.kernel.anno包下的类。该类型采用正则表达式,根据类的类名进行过滤 |
custom | com.kernel.XxxTypeFilter | 采用XxxTypeFilter通过代码的方式定义过滤原则。该类必须实现org.springframework.core.type.TypeFilter接口 |
Spring 还可以进行组件装配
\
构造器、普通字段、具有参数的方法都可以应用 @Autowired。
默认,所有被设置为该注解的属性都要被设置,否则会抛出异常,可以使用该注解的 required 属性设为false。
当 IOC 中存在多个类型兼容的 Bean 时,自动装配失败,此时可以在 @Qualifier 注解中提供 Bean 的名称。
@Authwired 注解应用在数组类型的属性上,此时 Spring 将会把所有匹配的 Bean 进行自动装配。
@Authwired 注解应用在集合属性上, 此时 Spring 读取该集合的类型信息,然后自动装配所有与之兼容的 Bean。
@Authwired 注解用在 Map 上时, 若该 Map 的键值为 String,那么 Spring 将自动装配与之 Map 值类型兼容的 Bean,此时 Bean 的名称作为键值。
配置方式
通过全类名
通过工厂方法
静态工厂
调用静态工厂创建 Bean 是将对象创建的过程封装到静态方法中,当调用者需要时,只需调用静态方法就可以返回对象。
要声明静态工厂创建 Bean,在 class 属性中指定静态工厂,同时在 \
实例工厂
调用实例工厂创建 Bean 是将对象封装到另一个对象的实例中,当调用者需要时,只需调用实例方法就可以返回对象。
要声明实例工厂创建 Bean,首先要声明一个实例工厂 Bean,然后在 \
Bean Factory
String 有两种 Bean,一种是普通的 Bean,另一种是 Bean Factory,它与普通的 Bean 不同,它返回的类型是是 getObject方法所返回的对象类型。
依赖注入
属性注入
200
构造器注入
内部 Bean
当 Bean 实例仅仅给一个特定的属性使用时,可以将其声明为内部 Bean,内部 Bean 声明在
集合属性
java.util.List 通过 \ 定义,标签里可以使用 \
java.util.Set通过 \ 一样。
java.util.Map 通过 \
java.util.Properties 通过 \
jdbc:MySQL:///test
使用 utility scheme 定义集合
使用基本的集合标签不能将集合作为单独的 Bean 定义,导致其他的 Bean 无法引入,可以使用 util schema 的集合标签定义独立的集合 Bean。
jdbc:mysql:///test
p 命名空间
为了简化 XML 的配置,Spring2.5 开始引入了一个新的 p 命名空间,可以通过元素属性的方式配置属性。
自动装配
可以使用的 autowire 属性设置自动装配,有两种方式:
byName:根据名称装配,属性名和要装配 Bean 名称必须完全相同,否则装配失败。
byType:根据类型装配,如果存在两个类型相同的 Bean,则装配失败。
缺点:对于一个 Bean,不能选择只装配其中的某一个属性,不够灵活,再一个是要么选择 byName,要么选择 byType,两者不能混搭。
Bean 之间的关系
继承关系
Spring 允许继承 Bean 的配置,子 Bean 从父 Bean 继承配置,如果父 Bean 只想作为模板,可以将父 bean 设为 abstract,并不是所有的 Bean 配置都会被继承,如果父 Bean 的 class 属性没有配置,它必须为抽象 Bean。
依赖关系
Soring 允许设置前置依赖,可以通过 depends-on 属性设置依赖 Bean,多个 Bean 通过逗号或空格隔开,依赖 Bean 在本 Bean 实例化之间实例化。
Bean 的作用域
在 Spring 中,允许在元素的 scope 属性设置 Bean 的作用域。
singleton:在初始化 IOC 容器的时候就会创建一个实例,再次获取,都会返回这一个实例。
prototype:在初始化 IOC 容器的时候不会创建实例,每次获取都会返回一个不同的实例。
request:每次请求 HTTP 都会返回一个新的 Bean 实例,仅适用于 WebApplicationContext。
seesion:同一个 HTTP Session 使用一个 Bean 实例,仅适用于WebApplicationContext。
使用外部属性文件
配置 Bean 时,有时候需要在配置文件中混入系统部署的细节信息,而这些部署文件要和 Bean 配置文件分离。Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器,这个处理器允许将部署信息存放到外置文件中,可以在 Bean 配置中使用 ${var} 的方式引入属性值。
SpEL
Spring 表达式语言,支持运行时查询和操作对象的表达式语言。
以#{}作为定界符。
支持算数、比较、逻辑运算符,支持字符串拼接和 if、else。
通过 SpEL 可以实现:
引用 bean
调用方法以及引入对象的属性
计算表达式的值
正则表达式的匹配
Bean的生命周期
Spring IOC 可以管理 Bean 的生命周期并允许在特定点执行定制任务。
Spring ICO 对 Bean 的生命周期管理的过程:
构造 Bean 实例。
为 Bean 设置属性。
初始化 Bean。
当容器关闭时,调用 Bean 的销毁方法。
在 Bean 的生命中可以通过 init-method 和 destroy-method 指定初始化和销毁方法。
Bean 的后置处理器允许在调用初始化方法之前对 Bean 进行额外处理。
Bean 的后置处理器对所有 Bean 实例逐一处理,对于 Bean 后置处理器来讲,必须实现 BeanPostProcessor,
Spring 将每个 Bean 传递给两个方法:
Object postProcessBeforeInitialization:在初始化方法调用前执行。
Object postProcessAfterInitialization:在初始化方法调用后执行。
添加 Bean 后置处理器后 Bean 的生命周期
构建 Bean 实例。
为 Bean 设置属性。
将 Bean 传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法。
初始化 Bean。
将 Bean 传递给 Bean 后置处理器的 postProcessAfterInitialization 方法。
当容器关闭时,调用 Bean 的销毁方法。
Spring 4.x 新特性:泛型依赖注入

创建两个泛型类,并配置两者的依赖关系,对于继承这两个类的子类,如果泛型相同,则会继承这种依赖关系。
Spring AOP
提出需求
当程序在运行期间需要给程序的运行增加一些特定需求,例如日志,可以修改代码实现,但是要修改的函数过多,就会特别麻烦。可以使用动态代理实现:
使用一个代理将对象包裹起来,让代理对象代替原对象执行方法。
public class ArithmeticCalculatorProxy {
// 被代理对象
private ArithmeticCalculator target = null;
public void ArithmeticCalculator(ArithmeticCalculator target) {
this.target = target;
}
public ArithmeticCalculator getProxy(){
// 代理对象
ArithmeticCalculator proxy;
// 代理对象用哪个类加载器加载
ClassLoader classLoader = target.getClass().getClassLoader();
// 代理对象的类型
Class[] interfaces = new Class[]{ArithmeticCalculator.class};
// 当代理对象执行其中的方法时的逻辑
InvocationHandler h = new InvocationHandler() {
/**
* @param proxy 要返回的代理对象
* @param method 正在被调用的方法
* @param args 传参
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("The method" + method.getName() + "begins with" + Arrays.asList(args));
Object result = method.invoke(args);
return result;
}
};
proxy = (ArithmeticCalculator) Proxy.newProxyInstance(classLoader, interfaces, h);
return proxy;
}
}
AOP 简介
面向切面编程(AOP)是对面向对象编程(OOP)的一个补充,AOP 的主要关注对象是切面(aspect)。
面向切面编程时,仍需定义公共功能,但可以明确定义功能在哪里,以什么方式应用,并且无需更改受影响的类。
AOP 的好处是:
每个事物逻辑位于一个文件,代码不分散,便于维护和升级。
业务模块更简洁,只包含核心业务代码。
AOP 术语:
切面:公共功能,在上例中切面就是日志功能。
通知:切面必须要完成的工作,上例中通知就是加减乘除。
目标:被通知的对象。
代理:代理类。
连接点:程序执行的某个特定位置。
切点:每个类拥有多个连接点,AOP 通过切点定位到特定的连接点。
AspectJ
Java 社区中最流行的 AOP 框架。
基于注解方式,要在 IOC 容器中添加注解支持,只需要在配置文件中添加,自动为匹配到类生成代理对象
要在 Spring 中声明切面,只需要将其声明为 Bean,当在 IOC 容器中声明切面类后,IOC 就会为那些与切面类匹配的类生成代理对象,切面是一个带有@Aspect 注解的 Java 类。
通知是标注有某种注解的 Java 方法。
Aspect 支持五种类型的通知注解:
@Before
/**
* 前置通知,方法执行前执行
*/
@Before("execution(* com.kernel.spring.aop.impl.ArithmeticCalculatorImpl.*(..) )")
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List