Spring笔记(一)——xml方式实现IoC和DI

本文详细介绍了Spring框架的基本概念及其核心特性IoC(控制反转)和DI(依赖注入)。通过实例展示了如何利用Spring进行对象管理和依赖注入,以及不同类型的注入方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

javaweb开发中,几乎离不开各种开源框架的支持。
javaweb的开发分为三个层次:

  • WEB层 (表现层)

  • 业务层 – Bean管理:(IOC)

  • 持久层 – Spring的JDBC模板.ORM模板用于整合其他的持久层框架
    在这三个层次中,常用的框架结构有SSH和SSM。无论是SSH还是SSM,业务层都是由Spring来实现的。因此,Spring框架对于javaweb开发非常重要。

    1.Spring简介

  • Spring是一个开源框架
  • Spring是于2003 年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。
  • 它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
  • Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以 从Spring中受益。
1.1 Spring的特点
* 方便解耦,简化开发
    * Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理

* AOP编程的支持
    * Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

* 声明式事务的支持
    * 只需要通过配置就可以完成对事务的管理,而无需手动编程
* 方便程序的测试

    * Spring对Junit4支持,可以通过注解方便的测试Spring程序
* 方便集成各种优秀框架

    * Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持
* 降低JavaEE API的使用难度

    * Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

2.Spring之IoC技术简介

IoC(Inverse of Control),控制反转,将对象的创建权反转给Spring,解决程序耦合性高的问题。
平常的开发中,我们创建一个对象,必须使用new这个关键词来完成。在javaweb的三层开发结构中,三个不同的层次的类之间进行调用。如果都使用new这个关键字来创建对象的实例。那么程序的耦合性会非常高,后期维护会很麻烦。
Spring的IoC技术,帮开发者创建和管理对象。只需要在配置文件中引入先关类的全路径,那么Spring会通过反射来帮助我们创建对象。我们不需要new对象,便可以安安心心的使用了。

2.1 需要导入的jar包

这里写图片描述
具体的jar包可以去spring的官网或者一些开源社区上去下载。其中第一个包是日志的jar包。

3. 代码实现IoC

创建两个测试类,一个是service层的类,一个是dao层的类。service层测类调用dao层的类。一般开发中,这两个类最好各自实现自己的接口,方便解耦。

public class MydaoImpl implements Mydao {

    public void save() {
    System.out.println("这里是持久层");
    }

}
public class MyServiceImpl implements MyService {
    private MydaoImpl myDao;
    private String name;
    private int age;
    private ArrayList<String> list;

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

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

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

    public void setMyDao(MydaoImpl myDao) {
        this.myDao = myDao;
    }

    @Override
    public void saveUser() {
        System.out.println("业务层保存用户");
    }

    public void printInfo(){
        System.out.println("age-"+age+"name-"+name);
    }

    public void testDI(){
        myDao.save();
    }

    public void printList(){
        for (String str : list) {
            System.out.println(str);
        }
    }
}
3.1 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"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="myservice" class="com.mq.service.MyServiceImpl">
</bean>

</beans>

该xml的名称为applicationContext.xml,名称可以改,但一般都为applicationContext。一般放在src目录下。

每一个需要被管理的类,放在在bean标签中进行配置,class是该类的全路径。id是给该类设置一个唯一的标志。

3.2 测试
public class MyTest {

    @Test
    public void f1(){
         // 使用Spring的工厂:

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类:
        MyServiceImpl userService = (MyServiceImpl) applicationContext.getBean("myservice");
        userService.saveUser();
    }

}

测试结果:

11:49:19,413  INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@46f5f779: startup date [Fri Jul 14 11:49:19 CST 2017]; root of context hierarchy
11:49:19,464  INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]
业务层保存用户

在调用MyServiceImpl的saveUser方法中,没有创建MyServiceImpl的实例,就可以直接调用该方法了。因为Spring已经帮我们创建了该类的实例对象。
这就是一个最简单的Spring实现IoC的例子。

4. DI

DI ( Dependency Injection),依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!

最常见的场景是,A类需要调用B类的方法,B类是A类的成员属性。并且要提供set方法。首先A类和B类都必须在applicationContext.xml配置文件中进行配置。
MyServiceImpl有三个属性,其中myDao是一个类的引用。这种形式在开发中非常常见。具体代码上面已经给出。

4.1 依赖注入的配置文件
<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="myservice" class="com.mq.service.MyServiceImpl">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="myDao" ref="mydao"></property>
</bean>

<bean id="mydao" class="com.mq.dao.MydaoImpl">
</bean>

</beans>

对于MydaoImpl和MyServiceImpl都进行了配置。在bean标签下,有property子标签,该标签就是用来配置依赖注入的。

property标签中,name表示在该类中的属性名称,该值必须和MyServiceImpl的属性一致。value表示给该属性赋值,如果该属性是基础类型或者String类型的话。ref表示引用。后面必须是另外一个已经配置的类的id值。
简而言之,在property标签中,name表示属性。如果属性是包括String类型在内的基础类型,使用value直接进行赋值。如果是该属性是其他类的引用,那么就使用ref

测试结果:

public class MyTest {

    @Test
    public void f1(){
         // 使用Spring的工厂:

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类:
        MyServiceImpl userService = (MyServiceImpl) applicationContext.getBean("myservice");
        //userService.saveUser();
        userService.printInfo();
        userService.testDI();
    }

}
12:12:09,241  INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@52d455b8: startup date [Fri Jul 14 12:12:09 CST 2017]; root of context hierarchy
12:12:09,287  INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]
age-15name-张三
这里是持久层

可见,MyServiceImpl中,我们没有new MyDaoImpl的实例对象,就可以调用MyDaoImpl的方法。

4.2 构造方法注入

这种方式用到的不是特别多,需要提供构造方法。

            public class Fruit {
                private String name;
                private double money;
                public Fruit (String name, double money) {
                    this.name = name;
                    this.money = money;
                }
            }

依赖注入的配置文件内容:

<bean id="fruit" class="com.mq.bean.Fruit">
                <constructor-arg name="name" value="香蕉"/>
                <constructor-arg name="money" value="100"/>
            </bean>
4.3数组集合和Properties的注入

以list集合为例,在MyServiceImpl中声明list属性,并且提供set方法。
配置文件中:

<bean id="myservice" class="com.mq.service.MyServiceImpl">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="myDao" ref="mydao"></property>

        <property name="list">
            <list>
                <value>吃饭</value>
                <value>睡觉</value>
            </list>
        </property>
</bean>

其中, 中的内容,就是赋给集合中的元素。

4.3.1 其他集合的注入方式
2. 如果是Set集合,注入的配置文件方式如下:
    <property name="set">
        <set>
            <value>上班</value>
            <value>下班</value>
        </set>
    </property>

3. 如果是Map集合,注入的配置方式如下:
    <property name="map">
        <map>
            <entry key="香蕉" value="3.8"/>
            <entry key="橘子" value="2"/>
            <entry key="苹果" value="1"/>
        </map>
    </property>

4. 如果是properties属性文件的方式,注入的配置如下:
    <property name="pro">
        <props>
            <prop key="name">root</prop>
            <prop key="password">test</prop>
        </props>
    </property>

5. Spring的其他标签的配置

bean标签中,除了最为常见的id和class子标签,还有其他标签。

  • name:给Bean起个名字。如果没有设置id标签,name可以当做id来使用。
  • scope:代表Bean的作用范围。有五个取值。
    * singleton         -- 单例(默认值)。
    * prototype         -- 多例,整合Struts2中,Action类是多例的,必须设置此属性。
    * request           -- 应用在Web项目中,每次HTTP请求都会创建一个新的Bean
    * session           -- 应用在Web项目中,同一个HTTP Session 共享一个Bean
    * globalsession     -- 应用在Web项目中,多服务器间的session
  • init-method:创建bean时调用init-method指定的方法
  • destroy-method:销毁该bean的实例事调用其指定的方法。

6. 其他

目前都只是在测试的方法中加载applicationContext.xml文件。每执行一次测试的方法,都需要重新加载配置文件,效率会比较低。
在web开发中,也不建议来一次请求,就先加载applicationContext.xml文件,再执行相应的方法。这样效率会非常低。
最好的方法时,在ServletContext创建的时候就加载该配置文件,不用每次请求来了都去加载。因此,需要一个listener进行监听ServletContext的创建。

第一步:首先需要导入spring-web-4.2.4.RELEASE.jar包。
第二步:配置监听器:

<!-- 配置Spring的核心监听器: -->
         <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
         </listener>
         <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
         </context-param>

第三步:在请求的方法中使用Bean

WebApplicationContext applicationContext =WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
        MyServiceImpl myservice= (MyServiceImpl) applicationContext.getBean("myservice")
        myservice.testDI();

这样,只有在项目启动的时候才会加载配置文件,我们直接在web层的接收请求的方法中,可以通过applicationContext对象直接获取相应的bean对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值