Spring IoC容器和AOP
1、Spring简单介绍
学习了spring,发现对spring的概念并不是特别理解,查阅了很多资料,资源乱七八糟的,参差不齐,看到合适的容易理解的并且觉得介绍的是正确的,遂做笔记摘抄与各位分享,如有错误,还请各位大佬批评指出
Spring有两大特性:
I
o
C
\color{red}{IoC}
IoC和
A
O
P
\color{red}{AOP}
AOP
IoC(Inversion of Control),意为控制反转
AOP(Aspect-Oriented Programming),意为面向切面编程
Spring核心容器的主要组件是Bean工厂(BeanFactory),Bean工厂使用控制反转(IoC)模式来降低程序代码之间的耦合度,并提供了面向切面编程(AOP)的实现。
简单说 S p r i n g 是 一 个 轻 量 级 的 控 制 反 转 ( I o C ) 和 面 向 切 面 编 程 ( A O P ) 的 容 器 框 架 \color{red}{Spring是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的容器框架} Spring是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的容器框架
2、Spring常用注解
在具体介绍IoC和AOP之前,我们先简要说明下Spring常用注解
常用注解 | 说明 |
---|---|
@Controller | 用于标注控制器层组件 |
@Service | 用于标注业务层组件 |
@Component | 用于标注这是一个受 Spring 管理的组件,组件引用名称是类名,第一个字母小写。可以使用@Component(“beanID”) 指定组件的名称 |
@Repository | 用于标注数据访问组件,即DAO组件 |
@Bean | 方法级别的注解,主要用在@Configuration和@Component注解的类里,@Bean注解的方法会产生一个Bean对象,该对象由Spring管理并放到IoC容器中。引用名称是方法名,也可以用@Bean(name = “beanID”)指定组件名 |
@Scope(“prototype”) | 将组件的范围设置为原型的(即多例)。保证每一个请求有一个单独的action来处理,避免action的线程问题。由于Spring默认是单例的,只会创建一个action对象,每次访问都是同一个对象,容易产生并发问题,数据不安全 |
@Autowired | 默认按类型进行自动装配。在容器查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中 |
@Resource | 默认按名称进行自动装配,当找不到与名称匹配的Bean时会按类型装配 |
如果能明确该类是一个控制器类组件的,用@Controller;能明确是一个服务类组件的,用@Service;能明确该类是一个数据访问组件的,用@Repository;不确定或不好区分的,但想让该类动态装配的用@Component。
@Controller、@Service、@Component、@Repository都是类级别的注解,如果一个方法也想动态装配,用@Bean。
当想按类型进行自动装配时,用@Autowired;当想按名称(beanID)进行自动装配时,用@Resource;当我们要根据需要(比如配置信息等)来动态装配不同的组件时,可以用getBean(“beanID”)。
3、控制反转(IoC)
控制反转,就是创建对象的控制权,被反转到了Spring框架上。
通常,我们实例化一个对象时,都是使用类的构造方法来new一个对象,这个过程是由我们自己来控制的,而控制反转就把new对象的工作交给了Spring容器,通过spring可以在容器中拿到对象
下面我找来一个例子帮助理解IoC(出处:IOC和AOP)
当一个公司需要新的员工或者其他什么资源时,传统的做法是公司自己进行招聘,有了中介之后,公司联系中介公司说我要什么样的员工(类),员工需要有什么样的技能(类的依赖类或者其他资源)。如果中介公司有这样的员工,交给公司。公司主动找人的过程就变成接受中介找到的员工,公司的主动权变为了被动接受。这就是控制反转。
IoC容器:具有依赖注入功能的容器,可以创建对象的容器。IoC容器负责实例化、定位、配置应用程序中的对象并建立这些对象之间的依赖。
4、依赖注入(DI)
DI(Dependency Injection)意为依赖注入。
依赖注入:由IoC容器动态地将某个对象所需要的外部资源(包括对象、资源、常量数据)注入到组件(Controller, Service等)之中。简单点说,就是IoC容器会把当前对象所需要的外部资源动态的注入给我们。
Spring依赖注入的方式主要有四个:基于注解注入方式、set注入方式、构造器注入方式、静态工厂注入方式。推荐使用基于注解注入方式,配置较少,比较方便。
5、面向切面编程(AOP)
面向切面编程(AOP)就是纵向的编程。比如业务A和业务B现在需要一个相同的操作,传统方法我们可能需要在A、B中都加入相关操作代码,而应用AOP就可以只写一遍代码,A、B共用这段代码。并且,当A、B需要增加新的操作时,可以在不改动原代码的情况下,灵活添加新的业务逻辑实现。
在实际开发中,比如商品查询、促销查询等业务,都需要记录日志、异常处理等操作,AOP把所有共用代码都剥离出来,单独放置到某个类中进行集中管理,在具体运行时,由容器进行动态织入这些公共代码。
AOP主要一般应用于签名验签、参数校验、日志记录、事务控制、权限控制、性能统计、异常处理等。
5.1 AOP涉及名词
切面(Aspect):共有功能的实现。如日志切面、权限切面、验签切面等。在实际开发中通常是一个存放共有功能实现的标准Java类。当Java类使用了@Aspect注解修饰时,就能被AOP容器识别为切面。
通知(Advice):切面的具体实现。就是要给目标对象织入的事情。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)5种。在实际开发中通常是切面类中的一个方法,具体属于哪类通知,通过方法上的注解区分。
连接点(JoinPoint):程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出等。Spring只支持方法级的连接点。一个类的所有方法前、后、抛出异常时等都是连接点。
切入点(Pointcut):用于定义通知应该切入到哪些连接点上,不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。
比如,在上面所说的连接点的基础上,来定义切入点。我们有一个类,类里有10个方法,那就产生了几十个连接点。但是我们并不想在所有方法上都织入通知,我们只想让其中的几个方法,在调用之前检验下入参是否合法,那么就用切点来定义这几个方法,让切点来筛选连接点,选中我们想要的方法。切入点就是来定义哪些类里面的哪些方法会得到通知。
目标对象(Target):那些即将切入切面的对象,也就是那些被通知的对象。这些对象专注业务本身的逻辑,所有的共有功能等待AOP容器的切入。
代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象本身业务逻辑加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。目标对象被织入共有功能后产生的对象。
织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译时、类加载时、运行时。Spring是在运行时完成织入,运行时织入通过Java语言的反射机制与动态代理机制来动态实现。
5.2 Pointcut用法
Pointcut格式为:
execution(modifier-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
修饰符匹配 modifier-pattern? 例:public private
返回值匹配 ret-type-pattern 可以用 * 表示任意返回值
类路径匹配 declaring-type-pattern? 全路径的类名
方法名匹配 name-pattern 可以指定方法名或者用 * 表示所有方法;set* 表示所有以set开头的方法
参数匹配 (param-pattern) 可以指定具体的参数类型,多个参数用“,”分隔;可以用 * 表示匹配任意类型的参数;可以用 (…) 表示零个或多个任意参数
异常类型匹配throws-pattern? 例:throws Exception
其中后面跟着 ? 表示可选项
例:
@Pointcut("execution(public * cn.wbnull. springbootdemo.controller.*.*(..))")
private void sign() {
}
参考该博主写的深入理解Spring两大特性:IoC和AOP
6、Spring核心jar包
Spring核心容器jar包
- B e a n s \color{red}{Beans} Beans :spring-beans-4.3.18.RELEASE.jar
- C o r e \color{red}{Core} Core :spring-core-4.3.18.RELEASE.jar
- C o n t e x t \color{red}{Context} Context :spring-context-4.3.18.RELEASE.jar
- E x p r e s s i o n \color{red}{Expression} Expression :spring-expression-4.3.18.RELEASE.jar
- Context support:spring-context-support-4.3.18.RELEASE.jar
测试:
- Test:spring-test-4.3.18.RELEASE.jar
面向切面编程:(核心)
- Aop:spring-aop-4.3.18.RELEASE.jar
- Aspects:spring-aspects-4.3.18.RELEASE.jar
数据访问和集成:
- JDBC:spring-jdbc-4.3.18.RELEASE.jar
- Transaction:spring-tx-4.3.18.RELEASE.jar
- ORM:spring-orm-4.3.18.RELEASE.jar
- OXM:spring-oxm-4.3.18.RELEASE.jar
- Messaging:spring-messaging-4.3.18.RELEASE.jar
- JMS:spring-jms-4.3.18.RELEASE.jar
Web远程调用:
- Web:spring-web-4.3.18.RELEASE.jar
- Web Servlet:spring-webmvc-4.3.18.RELEASE.jar
- Web portlet:spring-webmvc-portlet-4.3.18.RELEASE.jar
- Web Socket:spring-websocket-4.3.18.RELEASE.jar
依赖包
- commons-loggins…jar
各jar包作用
下面讲解各个jar包的作用(转自脚本之家)
♢
\color{red}{\diamondsuit}
♢ 1.org.springframework.aop或spring-aop.jar
这个jar文件包含在应用中使用Spring的AOP特性时所需的类。使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。
外部依赖spring-core.jar,spring-beans.jar,cglib-nodep.jar,aopalliance.jar
附:aopalliance.jar:这个包是AOP联盟的API包,里面包含了针对面向切面的接口。通常Spring等其它具备动态织入功能的框架依赖此包。
cglib-nodep.jar:这个包是一个强大的、高性能、高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。 当然这些实际的功能是asm所提供的,asm又是什么?Java字节码操控框架。cglib就是封装了asm,简化了asm的操作,实现了在运行期动态生成新的class。 实际上CGlib为spring aop提供了底层的一种实现;为hibernate使用cglib动态生成VO/PO (接口层对象)。
♡
\color{red}{\heartsuit}
♡ 2.spring-asm.jar
Spring独立的asm程序, Spring2.5.6的时候需要asmJar 包, 3.0开始提供他自己独立的asmJar。
♢
\color{red}{\diamondsuit}
♢ 3.spring-beans.jar
这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI 支持,引入spring-core.jar 及spring-beans.jar 文件就可以了。
外部依赖spring-core,cglib-nodep.jar。
♡
\color{red}{\heartsuit}
♡ 4.spring-core.jar
这个jar 文件包含Spring 框架基本的核心工具类。Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
外部依赖Commons-Logging, Log4J。
♢
\color{red}{\diamondsuit}
♢ 5.spring-aop.jar
这个jar 文件包含在应用中使用Spring 的AOP 特性时所需的类和源码级元数据支持。使用基于AOP 的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。
外部依赖spring-core,spring-beans,aopalliance,CGLIB,Commons Attributes。
♡
\color{red}{\heartsuit}
♡ 6.spring-context.jar
这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。
外部依赖spring-core.jar,spring-beans.jar,spring-aop.jar,commons-collections.jar,aopalliance.jar。
♢
\color{red}{\diamondsuit}
♢ 7.spring-dao.jar
这个jar 文件包含Spring DAO、Spring Transaction 进行数据访问的所有类。为了使用声明型事务支持,还需在自己的应用里包含spring-aop.jar。
外部依赖spring-core,spring-aop, spring-context, JTA API。
♡
\color{red}{\heartsuit}
♡ 8.spring-jdbc.jar
这个jar 文件包含对Spring 对JDBC 数据访问进行封装的所有类。
外部依赖spring-beans,spring-dao。
♢
\color{red}{\diamondsuit}
♢ 9.spring-support.jar
这个jar文件包含支持UI模版(Velocity,FreeMarker,JasperReports),邮件服务,脚本服务(JRuby),缓存Cache(EHCache),任务计划Scheduling(uartz)方面的类。
外部依赖spring-context, spring-jdbc, Velocity, FreeMarker, JasperReports, BSH, Groovy, JRuby, Quartz, EHCache
♡
\color{red}{\heartsuit}
♡ 10.spring-web.jar
这个jar 文件包含Web 应用开发时,用到Spring 框架时所需的核心类,包括自动载入Web Application Context 特性的类、Struts 与JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。
外部依赖spring-context, Servlet API, JSP API, JSTL, Commons FileUpload, COS。
♢
\color{red}{\diamondsuit}
♢ 11.spring-webmvc.jar
这个jar 文件包含Spring MVC 框架相关的所有类。包括框架的Servlets,Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的MVC 框架,则无需这个JAR 文件里的任何类。
外部依赖spring-web, spring-support,Tiles,iText,POI。
♡
\color{red}{\heartsuit}
♡ 12.spring-portlet.jar
spring自己实现的一个类似Spring MVC的框架。包括一个MVC框架和控制器。
外部依赖spring-web, Portlet API,spring-webmvc。
♢
\color{red}{\diamondsuit}
♢ 13.spring-struts.jar
Struts框架支持,可以更方便更容易的集成Struts框架。
外部依赖spring-web,Struts。
♡
\color{red}{\heartsuit}
♡ 14.spring-remoting.jar
这个jar 文件包含支持EJB、远程调用Remoting(RMI、Hessian、Burlap、Http Invoker、JAX-RPC)方面的类。
外部依赖spring-aop, (spring-context,spring-web,Hessian,Burlap,JAX-RPC,EJB API)。
♢
\color{red}{\diamondsuit}
♢ 15.spring-jmx.jar
这个jar包提供了对JMX 1.0/1.2的支持类。
外部依赖spring-beans,spring-aop, JMX API。
♡
\color{red}{\heartsuit}
♡ 16.spring-jms.jar
这个jar包提供了对JMS 1.0.2/1.1的支持类。
外部依赖spring-beans,spring-dao,JMS API。
♢
\color{red}{\diamondsuit}
♢ 17spring-jca.jar
对JCA 1.0的支持。JDO(Java Data Object )是Java对象持久化的新的规范,也是一个用于存取某种数据仓库中的对象的标准化API。
外部依赖spring-beans,spring-dao, JCA API。
♡
\color{red}{\heartsuit}
♡ 18.spring-jdo.jar
对JDO 1.0/2.0的支持。JCA (J2EE 连接器架构,Java Connector Architecture),可以将有JCA适配器其他语言的系统部署到j2ee应用服务器中
外部依赖spring-jdbc, JDO API, (spring-web)。
♢
\color{red}{\diamondsuit}
♢ 19.spring-jpa.jar
对JPA 1.0的支持。
外部依赖spring-jdbc, JPA API, (spring-web)。
♡
\color{red}{\heartsuit}
♡ 20.spring-hibernate2.jar
对Hibernate 2.1的支持,已经不建议使用。
外部依赖spring-jdbc,Hibernate2,(spring-web)。
♢
\color{red}{\diamondsuit}
♢ 21.spring-hibernate3.jar
对Hibernate 3.0/3.1/3.2的支持。
外部依赖spring-jdbc,Hibernate3,(spring-web)。
♡
\color{red}{\heartsuit}
♡ 22.spring-toplink.jar
对TopLink框架的支持。
外部依赖spring-jdbc,TopLink。
♢
\color{red}{\diamondsuit}
♢ 23.spring-ibatis.jar
对iBATIS SQL Maps的支持。
外部依赖spring-jdbc,iBATIS SQL Maps。
♡
\color{red}{\heartsuit}
♡ 24.spring-mock.jar
这个jar 文件包含Spring 一整套mock 类来辅助应用的测试。Spring 测试套件使用了其中大量mock 类,这样测试就更加简单。模拟HttpServletRequest 和HttpServletResponse 类在Web 应用单元测试是很方便的。并且提供了对JUnit的支持。
外部依赖spring-core。
♢
\color{red}{\diamondsuit}
♢ 25.spring-aspects.jar
提供对AspectJ的支持,以便可以方便的将面向方面的功能集成进IDE中,比如Eclipse AJDT。
外部依赖。
♡
\color{red}{\heartsuit}
♡ 26.spring-agent.jar
Spring的InstrumentationSavingAgent (为InstrumentationLoadTimeWeaver),一个设备代理包,可以参考JDK1.5的Instrumentation功能获得更多信息。
外部依赖none (for use at JVM startup: “-javaagent:spring-agent.jar”)。
♢
\color{red}{\diamondsuit}
♢ 27.spring-tomcat-weaver.jar
扩展Tomcat的ClassLoader,使其可以使用instrumentation(设备)类。
外部依赖none (for deployment into Tomcat’s “server/lib” directory)。