Spring入门(一)— IOC、DI

一、Spring介绍

  Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。

  Spring是2003年兴起的一个轻量级的java框架, 由 Rod Johnson 在其编著的《Expert one on one J2EE design and development》一书中阐述的思想和理念衍生而来。

  Spring 有两个核心 IOC & aop

  • IOC

IOC 的全称是 Inversion Of Control 翻译过来是控制反转的意思。 把对象的创建工作交给框架来完成

UserService userService = new UserServiceImpl(); ---> 问框架要对象

  • AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程

1. IOC的演变

  • 从早期的直接new具体类 ---> 面向接口编程

  • 面向接口编程 --使用工厂

  • 使用Spring来替代

2. Spring入门

  1. 导入jar包

    beans | code | context | expression 4个日志jar包 , log4j.properties

  2. 编写业务逻辑类
public interface UserService {
?
    void save();
}
?

public class UserServiceImpl implements UserService {
?
    @Override
    public void save(){
        System.out.println("调用了UserServiceImpl的save方法~!~!");
    }
?
}
  1. ml托管业务逻辑类

  在src下,创建一个xml, 名字随意。 applicationContext.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="us" class="com.pri.service.impl.UserServiceImpl"></bean>

</beans>
  1. 创建工厂,问工厂要对象
public class MainTest {
?
    @Test
    public void testSave(){
        /*
        UserService userService = new UserServiceImpl();
        userService.save();*/

        //1. 创建工厂
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 问工厂要实例对象
        UserService userService =(UserService) context.getBean("us");

        //3. 调用方法
        userService.save();
    }
}

3. 配置详解

  • xml解释
   <!--  bean 标签是用来告诉spring,需要帮忙创建什么类的实例 

        id | name : 标识符  , 以后拿着id的值就能问spring要对应类的实例。
        class : 托管类的全路径
        scope: 用于表示生成的实例模式
            spring默认生成的实例是单例。  scope="prototype" 表示生成多例

        init-method: 生成实例之后,调用的方法
        destroy-method: 销毁实例的时候调用的方法
   -->
    <bean id="us" class="com.pri.service.impl.UserServiceImpl" scope="prototype"
        init-method="init" destroy-method="destroy">
    </bean>
  • 代码解释
public class MainTest {
?
    @Test
    public void testSave(){
        /*
        UserService userService = new UserServiceImpl();
        userService.save();*/

        //1. 创建工厂 , 需要告诉工厂,xml文件在哪里。  不会这么写
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 问工厂要实例对象  , 可以让工厂送过来
        UserService userService =(UserService) context.getBean("us");

        //3. 调用方法
        userService.save();

        //关闭工厂  以后一般不关闭工厂
        ((AbstractApplicationContext) context).close();
    }
}

二、IOC实例化方式

  把对象交给spring创建的方式

1. 无参构造方法【重点】

  要求托管类的务必提供无参构造方法,当然以后可以配置让spring走有参构造

  • 代码
public class UserServiceImpl implements UserService {

    //spring创建实例, 要求托管类默认提供无参构造方法。
    @Override
    public void save(){
        System.out.println("调用了UserServiceImpl的save方法~!~!");
    }
}
  • 配置
<?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="us" class="com.pri.service.impl.UserServiceImpl"></bean>
</beans>

2. 静态工厂方法【了解】

要求提供工厂类,并且工厂的方法是静态方法, 在方法里面生成业务逻辑类的实例

  • 代码
public class StaticFactory {
?
    public static UserService getBean(){
        System.out.println("要创建UserServiceImpl的实例了~~");
        return new UserServiceImpl();
    }
}?
  • xml
<!-- 我们也是拿着us去问spring工厂要实例,  它直接就调用了StaticFactory的getBean方法拿到实例,然后返回 -->
<!-- 静态工厂配置 -->
<bean id="us" class="com.pri.factory.StaticFactory" factory-method="getBean"></bean>

3. 实例工厂方法【了解】

  • 代码
public class InstanceFactory {
?
    public UserService getBean(){
        System.out.println("要创建UserServiceImpl的实例了~~");
        return new UserServiceImpl();
    }
}
  • xml
<bean id="factory" class="com.pri.factory.InstanceFactory"/>
<bean id="us" factory-bean="factory" factory-method="getBean"></bean>

  后面的两种工厂的配置,开发当中几乎不会用。

三、依赖注入

  • 什么是依赖注入?

  DI : 全称是 dependency Injection 翻译过来是依赖注入 本意是在实例化对象的时候,对它里面的成员属性进行值的注入。

public class UserServiceImpl{

  private String name;

  //1. set方法
  public void setName(String name){
    this.name=name;
  }
}
?
?
UserServiceImpl us = new UserServiceImpl();
us.setName("zhangsan");
?
//现在实例的创建是工厂来完成,我们想让工厂创建实例的时候,顺便把成员变量给赋值了。
  • 给成员变量赋值的方式【DI的方式】

  ①set方法

  ②有参构造

1. 依赖注入的方式【重点】

注入的方式有两种: 有参构造 | set方法

  1. 采用有参构造完成依赖注入

  提供有参构造方法

  • 代码
public class UserServiceImpl implements UserService {

    private String address;
?
    public UserServiceImpl(String address) {
        super();
        this.address = address;
    }
?
    @Override
    public void save(){
        System.out.println("调用了UserServiceImpl的save方法~!~!=="+address);
    }
?
}
  • xml
<bean id="us" class="com.pri.service.impl.UserServiceImpl" >
    <!-- 指定构造的参数, name: 参数的名称, values: 参数的值 -->
    <constructor-arg name="address" value="深圳"/>
</bean>

2. 采用set方法完成依赖注入

  • 代码
public class UserServiceImpl implements UserService {

    private String address;
?
    public void setAddress(String address) {
        this.address = address;
    }
?
    @Override
    public void save(){
        System.out.println("调用了UserServiceImpl的save方法~!~!=="+address);
    }
}
  • xml
<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="us" class="com.pri.service.impl.UserServiceImpl" >
        <property name="address" value="宝安"/>
    </bean>
</beans>

2. 注入数据类型的演练

1. 集合类型

a. 数组类型
  • 代码
public class UserServiceImpl implements UserService{

    private String []  address;

    public void setAddress(String [] address) {
        this.address = address;
    }
  ...
}
  • xml
<property name="address" >
    <array>
        <value>北京1</value>
        <value>北京2</value>
        <value>我爱北京天安门,天安门很大</value>
    </array>
</property> 
b. list集合
  • 代码
public class UserServiceImpl implements UserService{
    private List<String>  address;

    public void setAddress(List<String> address) {
        this.address = address;
    }
  ...
} 
  • xml
<property name="address">
    <list>
        <value>北京1</value>
        <value>北京2</value>
        <value>我爱北京天安门,天安门很大</value>
    </list>
</property>
c. map集合
  • 代码
public class UserServiceImpl implements UserService{
?
    private Map<String ,Object> address;

    public void setAddress( Map<String ,Object> address) {
        this.address = address;
    }
    ...
}
  • xml
<property name="address">
    <map>
        <entry key="地址1" value="北京1"/>
        <entry key="地址2" value="北京2"/>
        <entry key="地址3" value="北京3"/>
    </map>
</property>

2. 对象类型

  • 代码
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
?
    @Override
    public void save(){
        System.out.println(" ==调用了UserServiceImpl的save方法~!~!==");

        /*UserDao userDao =new UserDaoImpl();  //创建对象  ---》 IOC  ----> bean标签
        userDao.save();*/

        //1. 我们自己创建对象,然后自己用。

        //2. 工厂创建对象,我们去问它要对象

        //3. 工厂创建对象,让工厂自己送过来对象。 --- 》 注入对象

        userDao.save();
    }
}
  • xml
<!-- 让spring创建UserServiceImpl的实例 -->
    <bean id="us" class="com.pri.service.impl.UserServiceImpl" >

<!-- 让spring调用UserServiceImpl的setUserDao的方法,并且把刚才创建好的ud的那个实例当成参数,传递进去。
        这就完成了对象的注入 -->
        <property name="userDao" ref="ud"></property>
    </bean>

    <!-- 让spring创建UserDaoImpl的实例 -->
    <bean id="ud" class="com.pri.dao.impl.UserDaoImpl"></bean>

3.注入的xml写法细节【了解】

依赖注入的方式已经固定化了,就是 有参构造 | set方法。 但是spring担心程序员在xml的配置要写的代码很多,然后程序员就不喜欢用了。所以spring针对xml的注入,提出了两种简化写法 : p 名称空间 | c名称空间

  • p 名称空间

针对的是这个<property name="" /> , 也就表明了代码里面声明注入的方式是 set方式

<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="us" class="com.pri.service.impl.UserServiceImpl" p:address="北京">
</bean>
  • c 名称空间

针对的是这个<constructor-arg/>, 也就要求我们的代码声明注入的方式必须是有参构造

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="us" class="com.pri.service.impl.UserServiceImpl" c:address="北京">
</bean> 
  • SPEL 属性注入

可以完成逻辑运算

<bean id="us" class="com.pri.service.impl.UserServiceImpl" >
        <property name="address"  value="#{1>2}"/>
</bean> 

四、整合Servlet

1. 初步整合

在servlet里面创建工厂、然后获取实例对象

public class ServletDemo extends HttpServlet {
?
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("调用了get方法~~~");
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService us = (UserService)context.getBean("us");
        us.save();
        ((AbstractApplicationContext) context).close();
    }
} 

2. 初步整合的问题

2个问题

1. 每次请求过来都会解析xml, 创建工厂。如果xml内容很多,就比较的耗时。解决方法:         工具类 | 静态代码块

2. 工厂创建的时机有点晚。 第一次使用的时候才会创建。 ?解决方法:        提前创建  --- 提前到项目发布 --- 项目发布之后,就会创建一个类的实例(ServletContext)-----ServletContextListner          a. 如果是我们自己处理的,  定义监听器, 然后在监听器里面创建工厂 , 存储工厂到一个地方去,以便所有的servlet都能使用到工厂。 servletContext.        b. 监听器不用你们写了,工厂创建的代码不用你们写了。放到servletcontext也不用写了。 配置监听器。

3. 进阶整合

把上面出现的问题给解决掉 ,必须要导入额外的jar包 spring-web-xxx.jar

只要项目一发布,就立即创建工厂,那么我们必须的抓住项目发布的这个契机。 以前在servlet阶段,学过一种东西监听器 ,可以监听作用域对象的创建与销毁 , SerlvetContext, 这是最大的作用域,全局只有一个对象。

  1. 在web.xml 中配置 监听器 并且配置param 指定spring配置文件所在
 <!--  配置listener,目的就是让项目发布的回收,能够创建工厂。但是创建工厂
  需要解析xml文件,它默认回到/WEB-INF/applicationContext.xml
  要是找不到就报错,除非我们告诉它,xml文件在哪里 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 告诉listener, 配置文件在哪里 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  1. 通过工具类获取之前创建好的工厂
public class ServletDemo extends HttpServlet {
?
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("调用了get方法~~~");

        //ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        UserService us = (UserService)context.getBean("us");
        us.save();
        //((AbstractApplicationContext) context).close();

    }
    ...
}

原文地址:https://www.cnblogs.com/gdwkong/p/8453053.html

时间: 2024-11-09 09:46:12

Spring入门(一)— IOC、DI的相关文章

Spring入门 (IOC)

1.实现原理 IOC:控制反转,指的是对象创建权反转(交给)Spring,作用是实现了程序的解耦合. 2.实现步骤 (1)    下载jar包(参见开发库/spring) (2)    创建web项目,导入jar包 (3)    书写配置文件,并注册对象到容器中 Xml文件名字与位置任意,建议放到src目录下起名为aoolicationContext.xml Xml中注册对象: (4)测试代码 3.Spring创建对象的三种方式(Bean创建方式) (1)工厂类: (2)配置文件: (3)   

Spring入门导读——IoC和AOP

和MyBatis系列不同的是,在正式开始Spring入门时,我们先来了解两个关于Spring核心的概念,IoC(Inverse of Control)控制反转和AOP()面向切面编程. 1.IoC(Inversion of Control)控制反转 什么是控制反转呢?可以这么通俗的来解释,我们通常写代码当一个类会关联另一个类是会直接在这个类里new,例如: 1 package day_30_spring; 2 3 /** 4 * @author 余林丰 5 * 6 * 2016年10月30日 7

Spring入门系列-IOC

什么是Spring Spring概述(了解) Spring是什么 Spring是JavaEE应用 full-stack轻量级开源框架,核心是:IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架. 什么是一站式开

Spring入门和IOC

本节要点: Spring简介 Spring特点 Spring框架组成 IOC和DI概念 项目中如何引入Spring框架 1 spring简介  spring:春天,寓意给软件行业带来了春天,由Rod Johnson提出 提出目的:解决企业应用开发的复杂性. 作用范围:任何Java应用 . 提出理念:使现有的技术更加实用,不去重复造轮子,让现有的框架运用更加合理.Struts和hibernate没有任何联系,所有spring最初的目的就是联系struts和hibernate,让他们运用的更好,本身

spring中的IOC/DI的知识点

IOC(Inverse of control):控制反转;其实就是一个装对象的容器,以前我们在controller中调用service中的方法,都要先new 一个service对象,这样不符合模式设计的六大法则中的依赖倒置原则,为了处理这个问题,可以把各层创建对象的工作让spring来完成,spring创建对象都把它放在ioc中 DI:依赖注入:其实与IOC是一回事,只是从不同的角度来看待问题的 实现IOC/DI的技术有: 1.setter注入(最常用) 2.构造方法注入(使用它时,要注意空构造

Spring入门介绍-IOC(二)

浅谈IOC IOC(inversion of control)是Spring的核心,贯穿始终.所谓IOC 就是有Spring来控制对象的生命周期和对象间的关系. 传统开发模式:对象之间相互依赖 IOC开发模式:IOC控制对象之间的依赖 IOC的理论背景 IOC和DI(依赖注入) IOC是控制反转.原先对象之间的关系式相互引用的,相对耦合度很高,一个对象的损坏可能会影响许多的对象,对象对其他对象的引用是自己控制的,如果把所以控制权都交给一个外部的第三方,统一管理应用,就实现了控制反转,降低了耦合度

Spring再接触 IOC DI

直接上例子 引入spring以及Junite所需要的jar包 User.java package com.bjsxt.model; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = userna

Spring入门--控制反转(IOC)与依赖注入(DI)

    1.控制反转(Inversion of Control)与依赖注入(Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理.所谓的"控制反转"概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器. IoC是一个很大的概念,可以用不同的方式来实现.其主要实现方式有两种:<1>依赖查找(Dependency Lookup)

Spring框架[一]——spring概念和ioc入门(ioc操作xml配置文件)

Spring概念 spring是开源的轻量级框架(即不需要依赖其他东西,可用直接使用) spring核心主要两部分 aop:面向切面编程,扩展功能不是修改源代码来实现: ioc:控制反转,比如:有一个类,在类中有个方法(非静态的方法),要调用类中的这个方法,则需要创建类的对象,使用对象调用方法.创建类对象的过程,需要new出来对象:而ioc则是将对象的创建不是通过new方式实现,而是交给spring配置来创建对象(即,将对象的创建交给spring来管理): spring是一站式框架 spring