放肆的自由自在🍺|

ywwwik

园龄:2年5个月粉丝:1关注:4

Spring相关理解

一、Spring简介

Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架,核心:IOC和AOP
主要优点:

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

二、Spring的体系结构

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

核心模块:

  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/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd"> 
    
        //配置要创建的类  
        <bean id="user" class="com.cad.domain.User"/>        
    </beans>
    复制代码

    (4) 进行测试

    复制代码
    //这只是用来测试的代码,后期不会这么写
    public class Test {
    
        @org.junit.Test
        public 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:// 例如 使用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); // true
        BufferedReader 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:\\Users\\ricco\\Desktop\\test\\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());
    }
}
复制代码

五、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/beans
    http://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.Test
    public 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。

 

本文作者:ywwwik

本文链接:https://www.cnblogs.com/ywwwik/p/17640527.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ywwwik  阅读(8)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Reol

作词 : Reol

fade away...do over again...

fade away...do over again...

歌い始めの一文字目 いつも迷ってる

歌い始めの一文字目 いつも迷ってる

どうせとりとめのないことだけど

伝わらなきゃもっと意味がない

どうしたってこんなに複雑なのに

どうしたってこんなに複雑なのに

噛み砕いてやらなきゃ伝わらない

ほら結局歌詞なんかどうだっていい

僕の音楽なんかこの世になくたっていいんだよ

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.

目の前 広がる現実世界がまた歪んだ

目の前 広がる現実世界がまた歪んだ

何度リセットしても

僕は僕以外の誰かには生まれ変われない

「そんなの知ってるよ」

気になるあの子の噂話も

シニカル標的は次の速報

麻痺しちゃってるこっからエスケープ

麻痺しちゃってるこっからエスケープ

遠く遠くまで行けるよ

安定なんてない 不安定な世界

安定なんてない 不安定な世界

安定なんてない きっと明日には忘れるよ

fade away...do over again...

fade away...do over again...

そうだ世界はどこかがいつも嘘くさい

そうだ世界はどこかがいつも嘘くさい

綺麗事だけじゃ大事な人たちすら守れない

くだらない 僕らみんなどこか狂ってるみたい

本当のことなんか全部神様も知らない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.