一、Sring简介

Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架。Spring核心是IOCAOP
Spring主要优点包括:

  • 方便解耦,简化开发,通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码造成的程序耦合度高。
  • AOP编程的支持,通过Spring提供的AOP功能,方便进行面向切面编程。
  • 声明式事务的支持,在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
  • 方便程序的测试,可以用非容器依赖的编程方式进行几乎所有的测试工作。
  • 方便集成各种优秀框架,Spring提供了对各种优秀框架的直接支持。

二、Spring体系结构

如下图所示,整个spring框架按其所属功能可以划分为五个主要模块,这五个模块几乎为企业应用提供了所需的一切,从持久层、业务层到表现层都拥有相应的支持,这就是为什么称Spring是一站式框架的原因。

核心模块(Core Container)

  Spring的核心模块实现了IoC的功能,它将类和类之间的依赖从代码中脱离出来,用配置的方式进行依赖关系描述。由IoC容器负责类的创建,管理,获取等。BeanFactory接口是Spring框架的核心接口,实现了容器很多核心的功能。

  Context模块构建于核心模块之上,扩展了BeanFactory的功能,包括国际化,资源加载,邮件服务,任务调度等多项功能。ApplicationContext是Context模块的核心接口。

  表达式语言(Expression Language)是统一表达式语言(EL)的一个扩展,支持设置和获取对象属性,调用对象方法,操作数组、集合等。使用它可以很方便的通过表达式和Spring IoC容器进行交互。

AOP模块

Spring AOP模块提供了满足AOP Alliance规范的实现,还整合了AspectJ这种AOP语言级的框架。通过AOP能降低耦合。

数据访问集成模块(Data Access/Integration )

该模块包括了JDBC、ORM、OXM、JMS和事务管理:

  • 事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和声明性的事务管理。
  • JDBC模块:提供了一个JBDC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。
  • ORM模块:提供与流行的“对象-关系”映射框架的无缝集成,包括hibernate、JPA、MyBatis等。而且可以使用Spring事务管理,无需额外控制事务。
  • OXM模块:提供了一个对Object/XML映射实现,将Java对象映射成XML数据,或者将XML数据映射成java对象,Object/XML映射实现包括JAXB、Castor、XMLBeans和XStream。
  • JMS模块:用于JMS(Java Messaging Service),提供一套“消息生产者、消息消费者”模板用于更加简单的使用JMS,JMS用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

Web模块

该模块建立在ApplicationContext模块之上,提供了Web应用的功能,如文件上传、FreeMarker等。Spring可以整合Struts2等MVC框架。此外,Spring自己提供了MVC框架Spring MVC。

测试模块

Spring可以用非容器依赖的编程方式进行几乎所有的测试工作,支持JUnit和TestNG等测试框架。

三、初识Ioc与DI

我们首先来讲解一下IoC的概念。IoC(控制反转:Inverse of Control)是Spring容器的核心,但是IoC这个概念却比较晦涩,让人不太容易望文生义。

1、IoC控制反转和DI依赖注入

  传统程序设计中,我们需要使用某个对象的方法,需要先通过new创建一个该对象,我们这时是主动行为;而IoC是我们将创建对象的控制权交给IoC容器,这时是由容器帮忙创建及注入依赖对象,我们的程序被动的接受IoC容器创建的对象,控制权反转,所以叫控制反转。

  由于IoC确实不够开门见山,所以提出了DI(依赖注入:Dependency Injection)的概念,即让第三方来实现注入,以移除我们类与需要使用的类之间的依赖关系。总的来说,IoC是目的,DI是手段,创建对象的过程往往意味着依赖的注入。我们为了实现IoC,让生成对象的方式由传统方式(new)反转过来,需要创建相关对象时由IoC容器帮我们注入(DI)。

  简单的说,就是我们类里需要另一个类,只需要让Spring帮我们创建 ,这叫做控制反转;然后Spring帮我们将需要的对象设置到我们的类中,这叫做依赖注入

2、常见的几种注入方法

  • 使用有参构造方法注入
public class  User{private String name;public User(String name){this.name=name;}
} User user=new User("tom");

  • 使用属性注入
public class  User{private String name;public void setName(String name){this.name=name;}
}User user=new User();user.setName("jack");

  • 使用接口注入
// 将调用类所有依赖注入的方法抽取到接口中,调用类通过实现该接口提供相应的注入方法。 public interface Dao{public void delete(String name);
} public class DapIml implements Dao{private String name;public void delete(String name){this.name=name;}
}

通过容器完成依赖关系的注入

上面的注入方式都需要我们手动的进行注入,如果有一个第三方容器能帮助我们完成类的实例化,以及依赖关系的装配,那么我们只需要专注于业务逻辑的开发即可。Spring就是这样的容器,它通过配置文件或注解描述类和类之间的依赖关系,自动完成类的初始化和依赖注入的工作。

3、Spring的IoC例子

(1) 创建工程,导入jar包

这里我们只是做IoC的操作,所以只需要导入核心模块里的jar包,beans、core、context、expression等。因为spring中并没有日志相关的jar包,所以我们还需要导入log4j和commons-logging。

(2) 创建一个类

public class User {public void add(){System.out.println("add.....");}
}

(3) 创建一个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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"> //配置要创建的类  <bean id="user" class="com.cad.domain.User"/>
</beans>

(4) 进行测试

//这只是用来测试的代码,后期不会这么写
public class Test {@org.junit.Testpublic void test(){//加载配置文件ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");//获取对象User user=(User) context.getBean("user");System.out.println(user);//调用方法user.add();}
}

在容器启动时,Spring会根据配置文件的描述信息,自动实例化Bean并完成依赖关系的装配,从容器中即可获得Bean实例,就可以直接使用。Spring为什么仅凭一个简单的配置文件,就能神奇的实例化并配置好程序使用的Bean呢?答案是通过 Java的反射技术

4、Spring的DI例子

我们的service层总是用到dao层,以前我们总是在Service层new出dao对象,现在我们使用依赖注入的方式向Service层注入dao层。

// UserDao
public class UserDao {public void add(){System.out.println("dao.....");}
}// UserService
public class UserService {UserDao userdao;public void setUserdao(UserDao userdao){this.userdao=userdao;}public void add(){System.out.println("service.......");userdao.add();}
}-------------------------------分割线--------------------------// 配置文件
<bean id="userdao" class="com.cad.domain.UserDao"></bean>
//这样在实例化service的时候,同时装配了dao对象,实现了依赖注入
<bean id="userservice" class="com.cad.domain.UserService">//ref为dao的id值<property name="userdao" ref="userdao"></property>
</bean>

四、Spring资源访问神器——Resource接口

JDK提供的访问资源的类(如java.NET.URL,File)等并不能很好很方便的满足各种底层资源的访问需求。Spring设计了一个Resource接口,为应用提供了更强的访问底层资源的能力,该接口拥有对应不同资源类型的实现类。

1、Resource接口的主要方法

  • boolean exists():资源是否存在
  • boolean isOpen():资源是否打开
  • URL getURL():返回对应资源的URL
  • File getFile():返回对应的文件对象
  • InputStream getInputStream():返回对应资源的输入流

Resource在Spring框架中起着不可或缺的作用,Spring框架使用Resource装载各种资源,包括配置文件资源,国际化属性资源等。

2、Resource接口的具体实现类

  • ByteArrayResource:二进制数组表示的资源
  • ClassPathResource:类路径下的资源 ,资源以相对于类路径的方式表示
  • FileSystemResource:文件系统资源,资源以文件系统路径方式表示,如d:/a/b.txt
  • InputStreamResource:对应一个InputStream的资源
  • ServletContextResource:为访问容器上下文中的资源而设计的类。负责以相对于web应用根目录的路径加载资源
  • UrlResource:封装了java.net.URL。用户能够访问任何可以通过URL表示的资源,如Http资源,Ftp资源等

3、Spring的资源加载机制

为了访问不同类型的资源,必须使用相应的Resource实现类,这是比较麻烦的。Spring提供了一个强大的加载资源的机制,仅通过资源地址的特殊标识就可以加载相应的资源。首先,我们了解一下Spring支持哪些资源类型的地址前缀:

  • classpath:例如classpath:com/cad/domain/bean.xml。从类路径中加载资源
  • file:例如 file:com/cad/domain/bean.xml.使用UrlResource从文件系统目录中加载资源。
  • http:// 例如http://www.baidu.com/resource/bean.xml 使用UrlResource从web服务器加载资源
  • ftp:// 例如frp://10.22.10.11/bean.xml 使用UrlResource从ftp服务器加载资源

Spring定义了一套资源加载的接口。ResourceLoader接口仅有一个getResource(String location)的方法,可以根据资源地址加载文件资源。资源地址仅支持带资源类型前缀的地址,不支持Ant风格的资源路径表达式。ResourcePatternResolver扩展ResourceLoader接口,定义新的接口方法getResources(String locationPattern),该方法支持带资源类型前缀以及Ant风格的资源路径的表达式。PathMatchingResourcePatternResolver是Spring提供的标准实现类。

4、例子

public class Test {public static void main(String[] args) throws IOException {ResourceLoader resloLoader = new DefaultResourceLoader();Resource res = resloLoader.getResource("https://www.baidu.com/");System.out.println(res instanceof UrlResource); // trueBufferedReader bf = new BufferedReader(new InputStreamReader(res.getInputStream()));StringBuilder sb = new StringBuilder();String temp = null;while ((temp = bf.readLine())!= null) {sb.append(temp);}System.out.println(sb.toString());System.out.println("n-----------------------------n");res = resloLoader.getResource("classpath:test.txt");bf = new BufferedReader(new InputStreamReader(res.getInputStream()));sb = new StringBuilder();temp = null;while ((temp = bf.readLine())!= null) {sb.append(temp);}System.out.println(sb.toString());System.out.println("n-----------------------------n");res = resloLoader.getResource("file:C:UsersriccoDesktoptesttest.txt");bf = new BufferedReader(new InputStreamReader(res.getInputStream()));sb = new StringBuilder();temp = null;while ((temp = bf.readLine())!= null) {sb.append(temp);}System.out.println(sb.toString());}
}

五、Spring的Ioc容器详解

1、BeanFactory

  BeanFactory是一个类工厂,和传统的类工厂不同,传统的类工厂仅负责构造一个类或几个类的实例;而BeanFactory可以创建并管理各种类的对象,Spring称这些被创建和管理的Java对象为Bean。

  BeanFactory是一个接口,Spring为BeanFactory提供了多种实现,最常用的就是XmlBeanFactory。其中,BeanFactory接口最主要的方法就是getBean(String beanName),该方法从容器中返回指定名称的Bean。此外,BeanFactory接口的功能可以通过实现它的接口进行扩展(比如ApplicationContext)。看下面的示例:

//我们使用Spring配置文件为User类提供配置信息,然后通过BeanFactory装载配置文件,启动Spring IoC容器。
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.cad.domain.User"></bean>
</beans>
// 我们通过XmlBeanFactory实现类启动Spring IoC容器
public class Test {@org.junit.Testpublic void test(){ //获取配置文件ResourcePatternResolver  resolver=new PathMatchingResourcePatternResolver(); Resource rs=resolver.getResource("classpath:bean.xml");//加载配置文件并启动IoC容器BeanFactory bf=new XmlBeanFactory(rs);//从容器中获取Bean对象User user=(User) bf.getBean("user");user.speak();}
}

XmlBeanFactory装载Spring配置文件并启动IoC容器,通过BeanFactory启动IoC容器时,并不会初始化配置文件中定义的Bean,初始化创建动作在第一个调用时。在初始化BeanFactory,必须提供一种日志框架,我们使用Log4J。

2、ApplicationContext

ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要编程方式来实现,而ApplicationContext中可以通过配置的方式来实现。ApplicationContext的主要实现类是ClassPathXmlApplicationContextFileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中加载配置文件,如下所示:

// 和BeanFactory初始化相似,ApplicationContext初始化也很简单
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");

ApplicationContext的初始化和BeanFactory初始化有一个重大的区别,BeanFactory初始化容器时并未初始化Bean,只有第一次访问Bean时才创建;而ApplicationContext则在初始化时就实例化所有的单实例的Bean。因此,ApplicationContext的初始化时间会稍长一点。

3、WebApplicationContext

WebApplicationContext是专门为Web应用准备的,它允许以相对于Web根目录的路径中加载配置文件完成初始化工作。从WebApplicationContext中可以获取ServletContext的引用,整个WebApplicationContext对象作为属性放置到ServletContext中,以便Web应用环境中可以访问Spring应用上下文。ConfigurableWebApplicationContext扩展了WebApplicationContext,允许通过配置方式实例化WebApplicationContext,定义了两个重要方法。

  • setServletContext(ServletContext servletcontext):为Spring设置ServletContext
  • setConfigLocation(String[] configLocations):设置Spring配置文件地址。

WebApplicationContext初始化的时机和方式是:利用Spring提供的ContextLoaderListener监听器去监听ServletContext对象的创建,当ServletContext对象创建时,创建并初始化WebApplicationContext对象。因此,我们只需要在web.xml配置监听器即可。

<!-- 利用Spring提供的ContextLoaderListener监听器去监听ServletContext对象的创建,并初始化WebApplicationContext对象 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Context Configuration locations for Spring XML files(默认查找/WEB-INF/applicationContext.xml) --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param>

4、BeanFactory、ApplicationContext和WebApplicationContext的联系与区别

Spring通过一个配置文件描述Bean与Bean之间的依赖关系,通过Java语言的反射技术能实例化Bean并建立Bean之间的依赖关系。Spring的IoC容器在完成这些底层工作的基础上,还提供了bean实例缓存、生命周期管理、事件发布,资源装载等高级服务。

  BeanFactory是Spring最核心的接口,提供了高级IoC的配置机制。ApplicationContext建立在BeanFactory的基础上,是BeanFactory的子接口,提供了更多面向应用的功能。我们一般称BeanFactory为IoC容器,ApplicationContext为应用上下文,也称为Spring容器。WebApplicationContext是专门为Web应用准备的,它允许以相对于Web根目录的路径中加载配置文件完成初始化工作,是ApplicationContext接口的子接口。

  BeanFactory是Spring框架的基础,面向Spring本身;ApplicationContext面向使用Spring框架的开发者,几乎所有的应用我们都直接使用ApplicationContext而非底层的BeanFactory;WebApplicationContext是专门用于Web应用。

5、父子容器

  通过HierarchicalBeanFactory接口,Spring的IoC容器可以建立父子层级关联的体系:子容器可以访问父容器的Bean,父容器不能访问子容器的Bean。

  Spring使用父子容器实现了很多功能,比如在Spring MVC中,控制器Bean位于子容器中,业务层和持久层Bean位于父容器中。但即使这样,控制器Bean也可以引用持久层和业务层的Bean,而业务层和持久层就看不到控制器Bean。

spring aop实例讲解_Spring核心技术详解(一)相关推荐

  1. spring aop实例讲解_Spring框架核心知识点

    文章内容输出来源:拉勾教育Java高薪训练营 前言: 由于工作需要提升自身技术能力,在各方比较下,报名了拉勾教育的java高薪训练营,目前已经学了半个月啦,来说说自身学习的感受吧: 课程内容有广度更有 ...

  2. 【Spring AOP】@Aspect结合案例详解(二): @Pointcut使用@within和within(已附源码)

    文章目录 前言 @within 完善打印日志案例 @within深入说明 within 匹配指定类 匹配指定包(package) 源码下载 总结 前言 在微服务流行的当下,在使用Spring Clou ...

  3. Spring AOP 增强框架 Nepxion Matrix 详解

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 概述 在<深入聊一聊 Spring AOP 实现机制>一文中,介绍了 Spring A ...

  4. 第14章-Spring AOP通知(Advice)详解

    文章目录 一.概述 二.通知的定义 1. 前置通知 2. 后置通知 3. 环绕通知 4. 最终通知 5. 异常通知 三.通知的参数 1. 切入点 2. 通知的参数传递 四.通知的顺序 五.附录 1. ...

  5. spring AOP解析之xml方式详解

    <aop:config>标签解析 aop名称空间的解析器是AopNamespaceHandler // 这里我们可以看到注册了几个解析器,重点关注ConfigBeanDefinitionP ...

  6. spring aop实例讲解_【好好面试】手把手调试,教你分析Spring-Aop

    [干货点] 此处是[好好面试]系列文的第11篇文章.看完该篇文章,你就可以了解Spring中Aop的相关使用和原理,并且能够轻松解答Aop相关的面试问题.更重要的是,很多人其实一看源码就头大,这次专门 ...

  7. Spring源码深度解析(五):Spring AOP原理及源码详解

    前言 OOP表示面向对象编程,是一种编程思想:AOP表示面向切面编程,也是一种编程思想,AOP的概念可以参考文章:SpringAOP基本概念详解. 正文 1.AbstractAdvisorAutoPr ...

  8. spring aop实例讲解_小实例理解Spring中的AOP----面向切面编程

    关于面向切面编程(Spring AOP),是在java面试中经常提及的,只有在充分理解了,日常工作中才能得心应手. 如何理解AOP呢?首先我们要思考为什么要使用切面编程,如下图: 对于一个系统来说保存 ...

  9. Spring AOP中定义切点PointCut详解

    1.AOP是什么? 软件工程有一个基本原则叫做"关注点分离"(Concern Separation),通俗的理解就是不同的问题交给不同的部分去解决,每部分专注于解决自己的问题.这年 ...

最新文章

  1. CodeSmith 学习资料收集
  2. 【斯坦福大学】可信任机器学习课程,附课件
  3. tcp传输中的序列号
  4. 测试音质好坏的软件,音响音质的好坏简单的两招测出
  5. eclipse中文乱码解决_解决git status显示中文文件名乱码问题
  6. 用户权限 英文_伴鱼绘本终身VIP卡+自然拼读精品课,完课返461元!英文原版绘本...
  7. 汇编语言实现led灯的跑马灯
  8. 浅谈CDQ分治与偏序问题
  9. Progressive Scramble 复杂模拟
  10. HTML5 classList 操作类名
  11. 大数据处理方面的 7 个开源搜索引擎
  12. Java数据库的JDBC编程
  13. 机器学习——概率模型
  14. (6.0系统)安卓神器XPOSED框架无需ROOT安装指南
  15. LLC谐振变换器学习二
  16. 合规安全大考核:移动应用安全策略全盘点
  17. 输入一个整数判断它是奇数还是偶数
  18. 大数据学习笔记:聚类分析
  19. 第五章 软件项目成本管理
  20. 【Java】Java获取昨天日期的正确姿势

热门文章

  1. 在控制台打印半径为R的圆
  2. ASP.NET MVC:Razor 引入命名空间
  3. 将数据库中一张表中数据复制到另一张表
  4. Lua和C的交互说明(函数)
  5. 转:VC++常用数据类型转换
  6. [NOIP2016]换教室(概率期望$DP$)
  7. Android开发之TextView的滚动显示
  8. 用触发器实现表的同步操作
  9. Linq(筛选与排序)
  10. MFC中使用自定义消息 .