【Spring篇】Spring的三大特性
文章目录
- Spring
- Spring的三大特性
Spring
1、概念:
是JAVAEE应用轻量级开源框架。
2、优缺点:
(1)优点:
- 方便解耦,简化开发。
Spring提供IOC容器,将对象间的依赖关系交由Spring进行控制。
- AOP编程的支持。
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
- 声明式事务的支持。
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质 量。
- 方便程序的测试。
集成Junit,方便测试。
- 方便集成各种优秀框架。
可集成SpringMVC、mybatis、Struts2、hibernate等框架。
- 减低JavaEE API的使用难度。
Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。
(2)缺点:
- Spring是一个轻量级的框架,却给人一种大而全的感觉。
- Spring依赖反射,反射影响性能。
- spring不支持分布式,不如springboot。
3、使用步骤
(1)导入maven坐标:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
(2)创建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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
(3)加载配置文件,并获取对象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService as = (AccountService)ac.getBean("accountService");
AccountDao adao = ac.getBean("accountDao",AccountDao.class);
4、bean的生命周期:
(1)Bean的定义。
(2)Bean的初始化 – init。
(3)Bean的使用。
(4)Bean的销毁 – destroy。
5、体系结构
Spring的三大特性
1、三大特征:AOP、IOC、DI。
IOC :控制反转。
DI :依赖注入。
AOP :面向切面编程。
2、IOC:控制反转。
(1)概念:控制反转。将创建对象的权利交给Spring来进行处理。
(2)作用:解耦(减低程序间的耦合性)。
(3)优缺点:
A、优点:
解耦,降低程序间的依赖关系;
B、缺点:
使用反射生成对象,损耗效率。
(4)实现步骤:(Spring注解开发IOC)
创建Spring主配置文件,并添加约束;
在主配置文件中,使用<context:component-scan>
标签,标明使用IOC的类所在的包;
使用注解标注IOC的类;
使用注解依赖注入的数据;
获取bean对象,并使用。
(5)涉及的注解:
@Component //用于标注一般类
@Controller //用于标注表现层的类
@Service //用于标注业务层的类
@Repository //用于标注持久层的类
@Autowired //自动按照类型注入
@Qualifier //在按照类中注入的基础之上, 再按照名称注入
@Resource //直接按照bean的id注入
- 前四个注解:
(1)作用:
让Spring自动创建当前类的对象,并把对象存入spring容器中。
(2)属性:
value:
用于指定bean的id,也就是对象放入容器后,对象的名字。
当我们不写时,默认值是当前类的类名(首字母改小写)。
- @Autowired:
①、作用:
①、自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
②、如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
③、如果Ioc容器中有多个类型匹配时, 对比变量名, 自动注入和当前变量名一样的ioc容器中的对象,如果没有则报错。
②、位置:
可以是变量上,也可以是方法上。
- @Qualifier:
①、作用:
①、在按照类中注入的基础之上, 再按照名称注入。
②、它在给类成员注入时不能单独使用。但是在给方法参数注入时可以。
②、属性:
value: 用于指定注入bean的id名称。
- @Resource:
①、作用:
直接按照bean的id注入。它可以独立使用, 相当于Autowired和Qualifier的结合。
②、属性:
name:用于指定bean的id。
③、注意:
JDK8可以使用,JDK9不能使用。
(3)、@Autowired和@Resource区别:
(1)@Autowired:自动按照类型type注入。
(2)@Resource:自动按照bean的id注入。可以独立使用,相当于Autowired和Qualifier的结合。
(4)、ApplicationContext的三个实现类:
①、顶层接口是BeanFactory。
②、三个实现类:
A、ClassPathXmlApplicationContext。
(可以加载类路径下的配置文件。要求配置文件必须是在类路径下,不在类路径下加载不了)
B、FileSystemXmlApplicationContext。
(可以加载磁盘任意路径下的配置文件,但是必须要有访问权限)
C、AnnotationConfigApplicationContext。(用于读取注解创建容器)
(5)、BeanFactory和ApplicationContext的区别:
BeanFactory:
①、 在构建核心容器时,采用延迟加载的方式创建对象。(即:什么时候根据ID获取对象了,什么时候才真正的创建对象)。
②、是Spring容器中的顶层接口。
ApplicationContext:
①、 在构建核心容器时,采用立即加载的方式创建对象。(即:只要一读取完配置文件马上就创建配置文件中配置的对象)。
②、是BeanFactory的子接口。
(6)、IOC中的bean标签:
作用:
①、用于配置对象让Spring来创建。
②、默认情况下,调用的是类中的无参构造函数。没有无参构造函数则不能创建成功。
属性:
①、id:给对象在容器中提供一个唯一标识。用于获取对象。
②、Class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
③、scope:指定对象的作用范围。
A、singleton: 单例的(默认值)。
B、prototype:多例的。
C、request:作用于web应用的请求范围。
D、session:作用于web应用的会话范围。
E、global session:作用于集群环境的会话范围,当不是集群时,它就是session。
④、init-method:指定类中的初始化方法名称。
⑤、destroy-method:指定类中销毁方法名称。
作用范围和生命周期:
①、单例对象:scope=“singleton”
A、一个应用只有一个对象的实例。它的作用范围就是整个引用。
B、生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
②、多例对象:scope=“prototype”
A、每次访问对象时,都会重新创建对象实例。
B、生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。
3、AOP:面向切面编程。
(1)概念:
面向切面编程。简单描述就是:将程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对自己的已有方法进行增强。
(2)作用:
在程序运行期间,不修改源码对已有方法进行增强。
(3)优缺点:
减少重复代码;
提高开发效率;
维护方便。
(4)实现方式:
使用动态代理技术。
(5)两种动态代理的区别(以及使用场景):
两种动态代理分别是:
JDK实现动态代理(基于接口的动态代理)、
CGLIB实现动态代理(基于子类动态代理)。
动态代理的特点:字节码随用随加载。
动态代理的作用:不修改源码的基础上对方法增强。
A、JDK实现动态地理:
(1)基于接口的动态代理。
(2) 涉及的类:Proxy。
(3)提供者:JDK。
(4)如何创建代理对象:使用Proxy类中的newProxyInstance方法创建代理对象。
(5)创建代理对象的要求:被代理类最少实现一个接口,才能使用代理创建代理对象。
(6)newProxyInstance方法的参数:
①、ClassLoader:类加载器。用于加载代理对象字节码,和被代理对象使用相同的类加载器。(固定写法)(代理谁写谁的classLoader:例如代理的是producer
)
②、Class[]:字节码数组。用于让代理对象和被代理对象有相同的方法。(固定写法)(例如,代理的是producer)
③、InvocationHandler:用于提供增强的代码。是让我们写如何代理。我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类。(此接口的实现类都是谁用谁写)。
invoke方法具有拦截的功能。作用:执行被代理对象的任何接口方法都会经过此方法。
invoke方法参数的含义:
proxy-------> 代理对象的引用。
method----> 当前执行的方法。
args--------> 当前执行方法所需的参数。
return返回值—> 和被代理对象方法有相同的返回值。
B、CGLIB实现动态代理:
(1)基于子类的动态代理。
(2)涉及的类:Enhancer。
(3)提供者:第三方CGLIB库。
(4)如何创建代理对象:使用Enhancer类的create方法。
(5)创建代理对象的要求:被代理类不能是最终类。(因为最终类不能创建子类)。
(6)create方法的参数:
①、Class:字节码。用于指定被代理对象的字节码。(要想代理谁,就写谁的.getClass())。
②、Callback:用于提供增强的代码。
intercept方法的三个参数:和基于接口的动态代理中的invoke方法的参数是一样的。
第四个参数:methodProxy—>当前执行方法的代理对象。
(6)使用动态代理实现事务控制。
(7)AOP相关术语:
①、JoinPoint(连接点):指那些被拦截到的点。(在Spring中这些点指的是方法,因为Spring只支持方法类型的连接点)。
②、PointCut(切入点):指的是要对哪些JoinPoint进行拦截的定义。
③、Advice(通知/增强):指拦截到JoinPoint之后所要做的事情。
④、Target(目标对象):代理的目标对象。
⑤、Weaving(织入):指把增强应用到目标对象来创建新的代理对象的过程。
spring采用动态代理织入;
Aspect采用编译器织入和类装载期织入。
⑥、Aspect(切面):是切入点和通知的结合。
(8)通知:
前置通知、后置通知、异常通知、最终通知、环绕通知。
前置通知:在切入点方法执行之前执行。
后置通知:在切入点方法执行之后执行。它和异常通知永远只能执行一个。
异常通知:在切入点方法执行产生异常之后执行。它和后置通知永远只能执行一个。
最终通知:无论切入点方法是否正常执行,它都会在其后面执行。
(9)涉及的注解:(Spring基于注解的AOP配置)
@Aspect:表示当前类是一个切面类。
@Before(“ptl()”):前置通知。
@AfterReturning(“ptl()”):后置通知。
@AfterThrowing(“ptl()”):异常通知。
@After(“ptl()”):最终通知。
@Around(“ptl()”):环绕通知。
4、DI:依赖注入。
(1) 作用:减低程序间的耦合。
(2)注入方式:使用构造函数注入;使用set方法注入;使用注解。
(3)能注入的数据:基本类型和string,其他bean类型(在配置文件或者注解配置过的bean),复杂类型/集合类型。
(4)构造函数注入:
①、使用的标签constructor-arg。
②、标签出现的位置:bean标签的内部。
③、标签中的属性:
type:用于指定要注入的数据类型,该数据类型也是构造函数中某个或某些参数的类型。
index:用于指定要注入的数据给构造函数中,指定索引位置的参数赋值。索引位置从0开始。
name:用于指定给构造函数中指定名称的参数赋值。
value:用于提供基本类型和string类型的数据。
ref:用于指定其他的bean类型数据。(指的是在spring的ioc核心容器中出现过的bean对象)。
④、优势:在获取bean对象时,必须要注入数据,否则对象无法创建成功。
⑤、坏处:
改变了bean对象的实例化方式,使我们在创建对象时,即使用不到这些数据,也要提供。
(5)set方法注入:(更常用的方法)
①、涉及的标签:property
②、出现的位置:bean标签的内部
③、标签的属性:
name:用于指定注入时所调用的set方法名称。
value:用于提供基本类型和string类型的数据。
ref:用于指定其他的bean类型数据,它指的就是在spring的IOC核心容器中出现过的bean对象。
④、优势:创建对象时没有明确的限制,可以直接使用默认构造函数。
⑤、坏处:如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
平淡啊张: 可以的啊,很细。
it噩梦: 总结的很好,加油