前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【框架】[Spring3]下载安装、开源框架与IoC控制反转详解

【框架】[Spring3]下载安装、开源框架与IoC控制反转详解

作者头像
谙忆
发布2021-01-21 11:11:34
5030
发布2021-01-21 11:11:34
举报
文章被收录于专栏:程序编程之旅程序编程之旅

转载请注明出处:http://blog.csdn.net/qq_26525215

昨天刚刚初学Spring3,也许Spring3有点老了哈,不过还是先把3学了再去学习4吧,首先先介绍一下如何去下载Spring的必须包吧。 (本篇博客适用于初学Spring的朋友)

java spring4现在不推荐使用xml配置文件… 当然啦,这些知识点在Spring4还是可以用的。

不过我在这里详解的还是Spring3哈,见谅~

下载SpringJAR包/文档:

Spring官网:http://spring.io/

Spring3.2版本以后(JAR/文档)的下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring/ (如果无法访问,请准备梯子)

选择一个需要下载的版本进去: 我选择的是最新的4.3.2版本.

spring-framework-*(版本号).RELEASE-dist.zip 包含了Spring必须的JAR包、DOC文档以及源代码等。

下载完之后解压我们就可以在spring-framework-4.3.2.RELEASE\libs找到需要包和DOC文档以及源代码了。

由于最新版本的已经提倡基于Java Config和注解的配置,不采用xml配置了,所以,我在这里准备的是Spring3.1.1版本的: 下载链接: https://github.com/chenhaoxiang/Java/blob/master/Spring/spring-framework-3.1.1.RELEASE.zip

Spring开源框架

Spring框架的起始:

Spring在英语中含义就是”春天”. 对于Java EE开发者来说,Spring框架出现确实带来了一股全新的春天的气息。 早在2002年,Rod Johson在其编著的《Expert one to one J2EE design and development》书中,对Java EE框架臃肿、低效、脱离现实的种种现状提出了很多质疑,并积极寻求探索革新之道。 由他主导编写了interface21框架,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。以interface21框架为基础,并集成了其它许多开源成果,于2004年3月24日,发布了1.0正式版取名为Spring。

Spring框架模块:

Spring的核心是个轻量级容器,实现了IoC(控制翻转)模式的容器,基于此核心容器所建立的应用程序,可以达到程序组件的松散耦合。这些特性都使得整个应用程序维护简化。 Spring框架核心由下图所示的七个模块组成。

现在来分别介绍一下这七个模块:

1、核心容器(Core)

这是Spring框架最基础的部分,它提供了依赖注入(Dependency Injection)特征来实现容器对Bean的管理。这里最基本的概念是BeanFactory,它是任何Spring应用的核心。BeanFactory是工厂模式的一个实现,它使用IoC将应用配置和依赖说明从实际的应用代码中分离出来。

2、AOP模块

AOP即面向切面编程技术,Spring在它的AOP模块中提供了对面向切面编程的丰富支持。AOP允许通过分离应用的业务逻辑与系统级服务(例如安全和事务管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责其它的系统级关注点,例如日志或事务支持。

3、对象/关系映射集成模块ORM

Hibernate是成熟的ORM产品,Spring并没有自己实现ORM框架而是集成了几个流行的ORM产品如Hibernate、JDO和iBATIS等。可以利用Spring对这些模块提供事务支持等。

4、JDBC抽象和DAO模块

Spring虽然集成了几个ORM产品,但也可以不选择这几款产品,因为Spring提供了JDBC和DAO模块。该模块对现有的JDBC技术进行了优化。你可以保持你的数据库访问代码干净简洁,并且可以防止因关闭数据库资源失败而引起的问题。

[JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构管管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。SpringDAO的面向JDBC的异常遵从从通用的DAO异常层次结构]

5、Spring的Web模块

Web上下文模块建立于应用上下文模块之上,提供了一个适合于Web应用的上下文。另外,这个模块还提供了一些面向服务支持。例如:实现文件上传的multipart请求,它也提供了Spring和其它Web框架的集成,比如Struts、WebWork。

6、应用上下文(Context)模块

核心模块的BeanFactory使Spring成为一个容器,而上下文模块使它成为一个框架。Web上下文模块建立于应用上下文模块之上,提供了一个适合于Web应用的上下文。该模块还提供了一些面向服务支持这个模块扩展了BeanFactory的概念,增加了对国际化(I18N)消息、事件传播以及验证的支持。

另外,这个模块还提供了许多企业服务,例如电子邮件、JNDI访问、EJB集成、远程以及时序调度(scheduling)服务。也包括对模版框架例如Velocity和FreeMarker集成的支持。

7、Spring的MVC框架

Spring为构建Web应用提供了一个功能全面的MVC框架。虽然Spring可以很容易地与其它MVC框架集成,例如Struts2,但Spring的MVC框架使用IoC对控制逻辑和业务对象提供了完全的分离。

Spring入门示例

将需要的Jar包导入项目、

再准备一个xml配置文件: applicationContext.xml 名字不一定要这个,自己可以随意改的,但建议使用这个名字。

准备的模板:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

</beans>

将Spring的压缩包解压后:你可以在spring-framework-3.1.1.RELEASE\projects\org.springframework.web.portlet\src\test\java\org\springframework\web\portlet\context\WEB-INF目录下找到applicationContext.xml。我们只需要这个部分就可以了。 将文件建立在src目录下(建在另外的路径也可以)。

导入必须的包,和建好applicationContext.xml文件。

1、编写一个普通的Java类(JavaBean)

代码语言:javascript
复制
package cn.hncu.demo1.domain;

public class Person {
    private String name;
    private int age;

    public Person() {
        System.out.println("执行Person的构造方法....");
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

2、在Spring配置文件applicationContext.xml。将JavaBean由Spring容器来管理。

代码语言:javascript
复制
<beans ...>
<!--scope属性值设为:prototype(每次获取都是一个新对象), request(同一个request中获取到的是同一个), session ,不设置,默认是单例 -->
    <bean id="p" class="cn.hncu.demo1.domain.Person" scope="prototype">
    </bean>
</beans>

测试方法:

代码语言:javascript
复制
    @Test
    public void demo1(){
        //此方法已在3.0版本中过时,不建议使用
        //BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

        //Spring3.0建议采用下面这种方式使用容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person p = (Person) ctx.getBean("p");//通过配置的id获得,需要强转
        System.out.println(p);

        Person p2 = ctx.getBean(Person.class);//通过Person的Class对象去获得,不需要强转
        System.out.println(p2);
    }

输出结果:

显然,Person只构造了一次。 由于我们没给初值,所以name是null,age因为是int型,所以是0.

现在我们在applicationContext.xml中来给它配置好初值,然后看:

代码语言:javascript
复制
    <!--scope属性值设为:prototype(每次获取都是一个新对象), request(同一个request中获取到的是同一个), session ,不设置,默认是单例 -->
    <bean id="p" class="cn.hncu.demo1.domain.Person">
        <!-- 配置好初始值 -->
        <property name="name" value="张三"></property>
        <property name="age" value="23"></property>
    </bean>

再一次的运行结果:

演示依赖(XML)注入

在servlet注入servicce,Person, 在servicce注入dao,

LoginDAO

代码语言:javascript
复制
package cn.hncu.demo1.login.dao;

import cn.hncu.demo1.domain.Person;

public interface LoginDAO {
    public void login(Person p);
}

LoginDaoJdbc

代码语言:javascript
复制
package cn.hncu.demo1.login.dao;

import cn.hncu.demo1.domain.Person;

public class LoginDaoJdbc implements LoginDAO{

    @Override
    public void login(Person p) {
        System.out.println("dao,到数据库中读取用户信息以进行登录....");     
        System.out.println("dao中获取的用户输入信息:"+p);     
    }

}

ILoginService

代码语言:javascript
复制
package cn.hncu.demo1.login.service;

import cn.hncu.demo1.domain.Person;

public interface ILoginService {

    public void login(Person p);

}

LoginServiceImpl

代码语言:javascript
复制
package cn.hncu.demo1.login.service;

import cn.hncu.demo1.domain.Person;
import cn.hncu.demo1.login.dao.LoginDAO;


public class LoginServiceImpl implements ILoginService{
    private LoginDAO dao = null;
    //如果要注入,需要注入的成员变量,必须写好set-get方法!

    public LoginDAO getDao() {
        return dao;
    }
    public void setDao(LoginDAO dao) {
        this.dao = dao;
    }

    @Override
    public void login(Person p) {
        dao.login(p);
    }

}

LoginAction

代码语言:javascript
复制
package cn.hncu.demo1.login;

import cn.hncu.demo1.domain.Person;
import cn.hncu.demo1.login.service.ILoginService;

public class LoginAction {
    private ILoginService service = null;
    private Person p = null;
    //如果要注入,需要注入的成员变量,必须写好set-get方法!
    public ILoginService getService() {
        return service;
    }
    public void setService(ILoginService service) {
        this.service = service;
    }
    public Person getP() {
        return p;
    }
    public void setP(Person p) {
        this.p = p;
    }

    public void execute(){
        service.login(p);
    }

}

需要依赖注入的变量一定要写好setter-getter 方法哦!!!

测试方法:

代码语言:javascript
复制
@Test//演示依赖(XML)注入
    public void demo2(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        LoginAction action = ctx.getBean(LoginAction.class);
        //LoginAction action = ctx.getBean("login",LoginAction.class);
        action.execute();
    }

配置文件:

代码语言:javascript
复制
<beans ...>
<!--scope属性值设为:prototype(每次获取都是一个新对象), request(同一个request中获取到的是同一个), session ,不设置,默认是单例 -->
    <bean id="p" class="cn.hncu.demo1.domain.Person">
        <!-- 配置好初始值 -->
        <property name="name" value="张三"></property>
        <property name="age" value="23"></property>
    </bean>

    <!-- 注意这里的class是实现类,而不是接口哦 -->
    <bean id="dao" class="cn.hncu.demo1.login.dao.LoginDaoJdbc">
    </bean>

    <!-- 注意这里的class也是实现类,而不是接口哦 -->
    <!-- 如果换实现类了,只需把这里的class变了就可以了 -->
    <bean id="s" class="cn.hncu.demo1.login.service.LoginServiceImpl">
        <!-- 实现类中还有变量,ref是另外的bean的id-引用 -->
        <property name="dao" ref="dao"></property>      
    </bean>

    <bean id="login" class="cn.hncu.demo1.login.LoginAction">
        <property name="service" ref="s"></property>
        <property name="person" ref="p"></property>
    </bean>
</beans>

结构图:

运行测试方法后的输出结果:

现在增加一个DAO的实现类,可以在程序中无需代码改变,就可以注入不同实例. 我们只需要改applicationContext.xml:

代码语言:javascript
复制
<!-- 注意这里的class是实现类,而不是接口哦 -->
    <!-- 如果换实现类了,只需把这里的class变了就可以了,或者不动这里,增加一个bean -->
    <bean id="dao" class="cn.hncu.demo1.login.dao.LoginDaoJdbc2">
    </bean>

增加的DAO实现类:

代码语言:javascript
复制
package cn.hncu.demo1.login.dao;

import cn.hncu.demo1.domain.Person;

public class LoginDaoJdbc2 implements LoginDAO{

    @Override
    public void login(Person p) {
        System.out.println("dao2,到数据库中读取用户信息以进行登录....");        
        System.out.println("dao2中获取的用户输入信息:"+p);        
    }

}

改动后的演示结果:

Spring IOC 控制反转

IoC(Inversion of Control)中文译为控制反转也可以叫做DI(Dependency Injection,依赖注入)。

控制反转模式的基本概念是:不直接创建对象,但是在xml配置文件中描述创建它们的方式。 在工程中使用该Bean时由Spring容器创建Bean的实例。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。

1、Spring注入(又称依赖注入DI):

其目的是为其中bean的属性赋值

通过Setter方法。(一般属性赋值即基本类型赋值示例)

第1步:编写JavaBean-必须写set方法

代码语言:javascript
复制
package cn.hncu.demo2.domain;

public class Cat {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Cat [name=" + name + "]";
    }

}

第2步: 在配置文件中注入属性的初始值

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <bean id="cat" class="cn.hncu.demo2.domain.Cat">
    <!-- 初始化name -->
        <property name="name" value="黑猫"></property>
    </bean>

</beans>

这样拿到的Cat对象就有初始值了,name的初始值为”黑猫”。

复杂数据类型的初始化:

例如,含有List,Map,Set,或者其他对象的数据,这样的bean对象如何初始化值呢。

结构如下:

Cat类就是前面那个。

User

代码语言:javascript
复制
package cn.hncu.demo2.domain;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class User {
    private String name;
    private Integer age;
    private List<Object> pets;
    private Map<String, Object> map;
    private Set<Object> set;
    private Object objs[];
    private Cat cat;


    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


    public List<Object> getPets() {
        return pets;
    }

    public void setPets(List<Object> pets) {
        this.pets = pets;
    }


    public Map<String, Object> getMap() {
        return map;
    }

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



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

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



    public Object[] getObjs() {
        return objs;
    }

    public void setObjs(Object[] objs) {
        this.objs = objs;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", pets=" + pets
                + "\r\n map=" + map + "\r\n set=" + set + "\r\n objs="
                + Arrays.toString(objs) + ", cat=" + cat + "]";
    }

}

配置文件

在这里我取名为:applicationContext2.xml了。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">


    <bean id="cat" class="cn.hncu.demo2.domain.Cat">
    <!-- 初始化name -->
        <property name="name" value="黑猫"></property>
    </bean>

    <bean id="user" class="cn.hncu.demo2.domain.User">
        <property name="name" value="Jack"></property>
        <property name="age" value="25"></property>

        <property name="pets">
            <list>
                <value>cat</value>
                <value>dog</value>
                <value>tiger</value>
            </list>
        </property>

        <property name="map">
            <map>
                <entry key="name" value="中国"></entry>
                <entry key="age" value="67"></entry>
                <!-- ref是引用 -->
                <entry key="cat" value-ref="cat"></entry>
            </map>
        </property>
        <property name="set">
         <set>
            <!-- 引用 -->
             <ref bean="cat"/>
             <value>aaa</value>
             <value>bbb</value>
         </set>
       </property>
        <property name="objs">
            <!-- 数组 -->
            <array>
                <value>hrllo</value>
                <ref bean="cat"/>
                <list>
                    <value>obj1</value>
                    <value>obj2</value>
                </list>
                <bean class="cn.hncu.demo2.domain.Cat">
                    <property name="name" value="白猫"></property>
                </bean>
            </array>
        </property>
    </bean>
</beans>

测试类:

代码语言:javascript
复制
package cn.hncu.demo2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.hncu.demo2.domain.User;

public class Demo2 {

    //演示spring中<bean>属性注入的一些细节
    @Test
    public void demo(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext2.xml");
        User user = ctx.getBean("user",User.class);
        System.out.println(user);
    }


}

测试结果:

如果对于这个User的类的赋值搞懂了,我想应该在这块就会很熟练了。

完整的项目源码:

https://github.com/chenhaoxiang/Java/blob/master/Spring/mySpring3Demo/mySpring3Demo.zip

本文章由[谙忆]编写, 所有权利保留。

转载请注明出处:http://blog.csdn.net/qq_26525215

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-08-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 下载SpringJAR包/文档:
  • Spring开源框架
    • Spring框架的起始:
      • Spring框架模块:
        • 1、核心容器(Core)
        • 2、AOP模块
        • 3、对象/关系映射集成模块ORM
        • 4、JDBC抽象和DAO模块
        • 5、Spring的Web模块
        • 6、应用上下文(Context)模块
        • 7、Spring的MVC框架
    • Spring入门示例
      • 准备的模板:
        • 演示依赖(XML)注入
          • LoginDAO
          • LoginDaoJdbc
          • ILoginService
          • LoginServiceImpl
          • LoginAction
          • 测试方法:
          • 配置文件:
          • 结构图:
          • 运行测试方法后的输出结果:
          • 增加的DAO实现类:
          • 改动后的演示结果:
      • Spring IOC 控制反转
        • 1、Spring注入(又称依赖注入DI):
          • 复杂数据类型的初始化:
            • User
            • 配置文件
            • 测试类:
            • 测试结果:
        • 完整的项目源码:
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档