初识Spring

9 篇文章 0 订阅

什么是Spring

Spring是Java EE编程领域的一个轻量级开源框架,该框架由一个叫Rod Johnson的程序员在 2002 年最早提出并随后创建,是为了解决企业级编程开发中的复杂性,实现敏捷开发的应用型框架。Spring是一个开源容器框架,它集成各类型的工具,通过核心的Bean factory实现了底层的类的实例化和生命周期的管理。在整个框架中,各类型的功能被抽象成一个个的 Bean,这样就可以实现各种功能的管理,包括动态加载和切面编程。

Spring的特点是什么

(1)方便解耦,简化开发

通过Spring提供的IOC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

(2)AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面编程,许多不容易用传统OOP(Object Oriented Programming,面向对象编程)实现的功能可以通过AOP轻松应付。

(3)声明式事务的支持

在Spring中,我们可以从单调烦闷的事物管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

(4)方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。

(5)方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。

(6)降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

(7)Java 源码是经典学习范例

Spring的源码设计精妙、结构清晰、匠心独运,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。

Spring的优势

  • 低侵入式设计,代码污染极低。
  • 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere。
  • Spring的DI机制降低了业务对象替换的复杂性,提高了组件之间的解耦。
  • Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。
  • Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
  • Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。

什么是耦合

在Spring中,通过Spring提供的IOC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。

  1. 耦合性,也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块之间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。
  2. 模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块之间的关系越多,其耦合性越强,同时表明其独立性越差。降低耦合性,可以提高其独立性
  3. 在软件工程中,耦合指的就是对象之间的依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应该让类和构件之间的耦合尽可能的小。在软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合
  4. 耦合是影响软件复杂度和设计质量的一个重要因素,在设计上面我们应该采用以下原则:如果模块间必须存在耦合,就尽量使用数据耦合,少使用控制耦合,限制公共耦合的范围,尽量避免使用内容耦合。

Spring的核心是什么

Spring的核心是:

  • IOC(Inverse of Control 控制反转)
  • AOP(Aspect Oriented Programming 面向切面编程)

IOC(控制反转)和DI(依赖注入)

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

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

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

常见的注入方式

常见的注入方法有使用有参构造方法注入和使用属性注入。现在有Person类和Car类,Spring配置文件为beans.xml。对应关系是一个Person类对象拥有一个Car类对象和一个name。代码如下:

  • Person类
public class Person {

    private String name;
    private Car car;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", car=" + car +
                '}';
    }
}
  • Car类
public class Car {

    private String name;
    private String color;
    private double price;

    public Car(){}

    public Car(String name, String color, double price) {
        this.name = name;
        this.color = color;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }
}

编辑Spring的配置文件beans.xml,对其进行注入。

  • 使用属性注入
    <bean id="person" class="cqucc.pojo.Person">
        <property name="name" value="奥利给" />
        <property name="car" ref="car" />
    </bean>
  • 使用有参构造方法注入
	<bean id="car" class="cqucc.pojo.Car">
       <constructor-arg name="name" value="五菱" />
       <constructor-arg name="color" value="white" />
       <constructor-arg name="price" value="10.8" />
    </bean>

注入完成后使用getBean()方法获取对象并输出,代码如下:

 @Test
 public void testPerson() {
     String config = "beans.xml";
     ApplicationContext ac = new ClassPathXmlApplicationContext(config);
     Person p = (Person) ac.getBean("person");
     System.out.println(p);
 }

属性注入成功,运行结果如下:
在这里插入图片描述

集合属性的注入

创建一个类CollectionTest和Spring配置文件CollectionTest.xml。类中有List类型的list,Map类型的map和Set类型的set,我们将对它们进行属性注入。

  • CollectionTest类
public class CollectionTest {

    List<String> list;
    Set<String> set;
    Map<String,Integer> map;

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    public List<String> getList() {
        return list;
    }

    public Set<String> getSet() {
        return set;
    }

    public Map<String, Integer> getMap() {
        return map;
    }
}
  • CollectionTest.xml文件:
    <bean name="collection" class="cqucc.pojo.CollectionTest">
        <property name="list">
            <list>
                <value>list元素1</value>
                <value>list元素2</value>
                <value>list元素3</value>
            </list>
        </property>

        <property name="set">
            <set>
                <value>set元素s1</value>
                <value>set元素s2</value>
                <value>set元素s3</value>
            </set>
        </property>

        <property name="map">
            <map>
                <entry key="map元素1" value="1"></entry>
                <entry key="map元素2" value="2"></entry>
                <entry key="map元素3" value="3"></entry>
            </map>
        </property>
    </bean>

测试代码及运行结果如下:
在这里插入图片描述

Spring bean的作用域

Spring bean有五大作用域,分别是:
在这里插入图片描述
后三个作用域是需要使用Spring的WebApplicationContext,所以着重介绍singleton和prototype作用域。

(1)singleton作用域

配置了 scope=“singleton” 的 bean 为单例作用域。此作用域为Spring bean的默认作用域。Spring 以容器的方式,使得我们仅需配置,即可得到天然的单例模式。因为 Spring 的超强能力,所以在实际应用中,大部分 Bean 都能以单例方式运行 ,这也是 bean 的默认作用域指定为 singleton 的原因 。使用singleton的bean在同一个Spring IOC容器中只会有一个实例。将一个bean设置为singleton的方式如下:

<bean name="collection" class="cqucc.pojo.CollectionTest" scope="singleton">

(2)prototype作用域

配置了 scope=“prototype” 的 bean 为非单例作用域,即使用prototype的bean在同一个Spring IOC容器中可以有多个实例。在默认情况下, Spring 容器在启动时不实例化 prototype 的 bean。此外,Spring 容器将 prototype 的bean 交给调用者后,就不再负责管理它的生命周期。将一个bean设置为prototype的方式如下:

<bean name="collection" class="cqucc.pojo.CollectionTest" scope="prototype">

Spring bean的生命周期

创建一个类BeanLife和Spring配置文件BeanLife.xml,用于测试无参构造方法、init方法和destroy的调用顺序。

  • BeanLife类
public class BeanLife {

    public BeanLife() {
        System.out.println("调用无参构造方法");
    }

    public void init() {
        System.out.println("初始化bean");
    }

    public void destroy() {
        System.out.println("销毁bean");
    }
}
  • BeanLife.xml文件
    <bean name="life" class="cqucc.pojo.BeanLife" init-method="init" destroy-method="destroy">
    </bean>

测试方法和运行结果如图:
在这里插入图片描述
由运行结果可以知道,类中的构造方法优先调用,然后才会调用初始化函数。销毁函数只有以ClassPathXmlApplicationContext来创建对象调用getBean()方法后,调用close()函数才会执行。

Spring bean的两种获取方式

(1)通过BeanFactory获取

BeanFactory是一个类工厂,和传统的类工厂不同,传统的类工厂仅负责构造一个类或几个类的实例;而BeanFactory可以创建并管理各种类的对象,Spring称这些被创建和管理的Java对象为Bean。BeanFactory是一个接口,Spring为BeanFactory提供了多种实现,最常用的就是XmlBeanFactory。其中,BeanFactory接口最主要的方法就是getBean(String beanName),该方法从容器中返回指定名称的Bean。此外,BeanFactory接口的功能可以通过实现它的接口进行扩展(比如ApplicationContext)。以获取上面BeanLife对象为例,代码如下:

  //获取配置文件
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource rs = resolver.getResource("classpath:BeanLife.xml");

//加载配置文件并启动IOC容器
BeanFactory bf = new XmlBeanFactory(rs);
//从容器中获取Bean对象
BeanLife b = (BeanLife) bf.getBean("life");

(2)通过ApplicationContext获取
ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要编程方式来实现,而ApplicationContext中可以通过配置的方式来实现。ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中加载配置文件。
上面的对象获取方式都是通过ApplicationContext获取。以获取上面BeanLife对象为例,代码如下:

String config = "BeanLife.xml";
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(config);
BeanLife b = (BeanLife) ac.getBean("life");

参考文章

https://blog.csdn.net/justloveyou_/article/details/73136260?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163152014416780261951617%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163152014416780261951617&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-73136260.first_rank_v2_pc_rank_v29&utm_term=spring核心&spm=1018.2226.3001.4187

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值