【框架】---->Spring 01 (IOC的实现)

文章目录

  • 一、Spring概述
  • 二、Spring体系结构
  • 三、程序开发步骤
    • 1、原始开发步骤
    • 2、利用Spring框架开发步骤
  • 四、Spring配置文件
    • 1、Bean标签基本配置
    • 2、Bean标签范围配置
    • 3、Bean生命周期配置
    • 4、Bean实例化的三种方式
    • 5、Bean依赖注入
      • 依赖注入的数据类型
    • 6、引入其他配置文件
  • 五、Spring相关API
    • 1、ApplicationContext的继承体系
    • 2、ApplicationContext的实现类
    • 3、getBean()方法使用
  • 六、Spring的优势


一、Spring概述

  Soring是分层的javaSE/EE应用full_stack(全站)轻量级开源框架,以loc(inverse Of Contorl:反转控制)和AOP(面向切面编程)为内核

  Spring提供了(展现层SpringMVC)和(持九层SpringJDBCTemplate)以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的javaEE企业应用开源框架。


二、Spring体系结构

【框架】---->Spring 01 (IOC的实现)_第1张图片


三、程序开发步骤

1、原始开发步骤

第一步:创建Dao层

UserDao接口:

public interface UserDao {
    public void save();
}

接口实现类:

public class UserDaoimpl implements UserDao {
    @Override
    public void save() {
        System.out.println("........");
    }
}

第二步:创建service层
UserService接口:

public interface UserService {
    public void save();
}

接口实现类:

public class UserServiceimpl implements UserService {
    private UserDao userDao = new UserDaoimpl();

    @Override
    public void save() {
        userDao.save();
    }
}

第三步:测试代码

public class UserTest {
    private UserService userService = new UserServiceimpl();
    @Test
    public void test() {
        userService.save();
    }
}

测试结果:

........

进程已结束,退出代码0

2、利用Spring框架开发步骤

【框架】---->Spring 01 (IOC的实现)_第2张图片

第一步:导入 Spring 开发的基本包坐标

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
    </dependencies>

第二步:创建Dao层

这里接口和实现类代码和原始开发相同就略过

第三步:创建 Spring 核心配置文件,在配置文件中配置 UserDaoImpl

applicationContex.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="userDao" class="com.dao.impl.UserDaoimpl"/>
</beans>

第四步:使用 Spring 的 API 获得 Bean 实例进行测试

public class userTest {
    public static void main(String[] args) {
        //获得 Bean 实例
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
        //
        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

测试结果

【框架】---->Spring 01 (IOC的实现)_第3张图片


四、Spring配置文件

1、Bean标签基本配置

  用于配置对象由Spring来创建,默认情况下调用的是类中的无参构造函数,如果没有无参构造函数则创建失败。

基本属性:

id:Bean实例在Spring容器中的唯一标识
class:Bean的全限定名称

2、Bean标签范围配置

scope:指对象的作用范围,具体取值有:
【框架】---->Spring 01 (IOC的实现)_第4张图片
按例:
在Bean中加入scope属性:

 <bean id="userDao" class="com.dao.impl.UserDaoimpl" scope="singleton"/>

测试代码:

    @Test
    //测试scope属性
    public void test1() {
        //获得 Bean 实例
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
        UserDao userDao1 = (UserDao) app.getBean("userDao");
        UserDao userDao2 = (UserDao) app.getBean("userDao");
        System.out.println(userDao1);
        System.out.println(userDao2);
    }

运行结果:
【框架】---->Spring 01 (IOC的实现)_第5张图片
地址相同代表现容器中只有一个对象。

其它代码保持不变,将singleton改为prototype时运行结果为:
【框架】---->Spring 01 (IOC的实现)_第6张图片
地址不一样代表现在容器中存在多个对象。

结论
  当scope="singleton"时,Spring核心文件被加载时,创建Bean


 - 对象创建:当应用加载,创建容器时,对象就被创建
 - 对象运行:只要容器在,对象一直活着
 - 对象销毁:当应用卸载,销毁容器时,对象就被销毁

  当scope="prototype"时,每调用一次getBean()方法就创建一个bean


 - 对象创建:当使用对象时,创建新的对象实例
 - 对象运行:只要对象在使用中,就一直活着
 - 对象销毁:当对象长时间不用时,就会被java的垃圾回收器回收

3、Bean生命周期配置

init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称

按例:
在Dao实现类(在原基础上加了两个方法):

public class UserDaoimpl implements UserDao {
    public UserDaoimpl() {
        System.out.println("UserDaoimpl创建");
    }

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

    public void destroy() {
        System.out.println("销毁方法");
    }

    @Override
    public void save() {
        System.out.println("........");
    }
}

核心配置文件为:

 <bean id="userDao" class="com.dao.impl.UserDaoimpl"/>

在不做其他操作下运行结果为:

【框架】---->Spring 01 (IOC的实现)_第7张图片
在配置文件中加上初始化方法和销毁方法:

<bean id="userDao" class="com.dao.impl.UserDaoimpl" init-method="init" destroy-method="destroy"/>

运行结果为:
【框架】---->Spring 01 (IOC的实现)_第8张图片

4、Bean实例化的三种方式

  1. 无参构造方法实例化
  2. 工厂静态方法实例化
    按例:

创建一个对象工厂类,里有一个静态方法:

public class StaticFactory {
    public static UserDao getUserDao() {
        return new UserDaoimpl();
    }
}

配置文件该改为:

 <bean id="userDao" class="com.factory.StaticFactory" factory-method="getUserDao"/>

运行结果:
【框架】---->Spring 01 (IOC的实现)_第9张图片

  1. 工厂实例方法实例化

案例:
创建一个工厂类:

public class DynamicFactory {
    public UserDao getUserDao() {
        return new UserDaoimpl();
    }
}

配置如下:

    <bean id="factory" class="com.factory.DynamicFactory" />
    <bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>

测试结果:
【框架】---->Spring 01 (IOC的实现)_第10张图片

5、Bean依赖注入

前面的按例是让Spring去实例化Dao层的对象,下面将以web层和业务层来进行讲解。
按例:
Service实现类:

public class UserServiceimpl implements UserService {
    @Override
    public void save() {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
}

相关配置:

    <bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
    <bean id="userService" class="com.service.impl.UserServiceimpl"/>

在web层创建一个类进行测试:

public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

测试结果:
【框架】---->Spring 01 (IOC的实现)_第11张图片
  由案例可知,userDao和userService都存在于Spring容器中,当Service层要用到Dao层就要从容器中获取,而web层只对Service进行操作如下图所示。
【框架】---->Spring 01 (IOC的实现)_第12张图片

  因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在Spring容器中,将UserDao设置到UserService内部,这时候就要用到依赖注入了,如下图所示。
【框架】---->Spring 01 (IOC的实现)_第13张图片
依赖注入概念:依赖注入是Spring框架核心IOC的具体实现

【框架】---->Spring 01 (IOC的实现)_第14张图片

依赖注入方式(将UserDao注入到UserService内部)

1、构造方法

按例:
在service的实现类中生成有参构造方法:

public class UserServiceimpl implements UserService {
    private UserDao userDao;
    public UserServiceimpl(UserDao userDao) {
        this.userDao = userDao;
    }
    public UserServiceimpl() {
    }
    @Override
    public void save() {
        userDao.save();
    }
}

配置文件中的配置:

   <bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
    <bean id="userService" class="com.service.impl.UserServiceimpl">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

测试运行结果略

2、set方法
按例:
将service的实现类改为:

public class UserServiceimpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.save();
    }
}

在配置文件中将userDao注入给userService,配置文件为:

 <bean id="userDao" class="com.dao.impl.UserDaoimpl"/>
    <bean id="userService" class="com.service.impl.UserServiceimpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

除了上面的配置方法还有一种较简单的配置方法p命名空间注入:

先引入p命名空间,再修改注入方式,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       //p命名空间
       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="userDao" class="com.dao.impl.UserDaoimpl"/>
    //注入对象
    <bean id="userService" class="com.service.impl.UserServiceimpl" p:userDao-ref="userDao"></bean>
</beans>

运行结果和前面相同就略过了

依赖注入的数据类型

前面都是通过对象的引用进行注入的,除了引用数据类型之外还可以注入普通数据类型、集合数据类型。

普通数据类型注入按例:
在Dao实现类中设置两个属性:

public class UserDaoimpl implements UserDao {
    private String name;
    private int age;

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

    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public void save() {
        System.out.println(name+"==="+age);
        System.out.println("........");
    }
}

配置文件配置如下:

<bean id="userDao" class="com.dao.impl.UserDaoimpl">
        <property name="name" value="tom"/>
        <property name="age" value="18"/>
    </bean>

运行结果:
【框架】---->Spring 01 (IOC的实现)_第15张图片
集合数据类型注入案例:
Dao实现类:

public class UserDaoimpl implements UserDao {
    private List<String> stringList;
    private Map<String, User> userMap;
    private Properties properties;

    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }

    public void setUserMap(Map<String, User> userMap) {
        this.userMap = userMap;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    @Override
    public void save() {
        System.out.println(stringList);
        System.out.println(userMap);
        System.out.println(properties);
        System.out.println("........");
    }
}

配置文件配置:

 <bean id="userService" class="com.service.impl.UserServiceimpl">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>
    <bean id="userDao" class="com.dao.impl.UserDaoimpl">
        <property name="stringList" >
            <list>
                <value>招财</value>
                <value>进宝</value>
            </list>
        </property>
        <property name="userMap">
            <map>
               <entry key="1:" value-ref="user1"></entry>
                <entry key="2:" value-ref="user2"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="欠债">还钱</prop>
                <prop key="杀人">偿命</prop>
            </props>
        </property>
    </bean>
    <bean id="user1" class="com.domain.User">
        <property name="name" value="荣华"/>
        <property name="age" value="18"/>
    </bean>
    <bean id="user2" class="com.domain.User">
        <property name="name" value="富贵"/>
        <property name="age" value="18"/>
    </bean>

User实体类略
运行结果:
【框架】---->Spring 01 (IOC的实现)_第16张图片

6、引入其他配置文件

  实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载

<import resource="XXXX.xml"/>

五、Spring相关API

public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContex.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

1、ApplicationContext的继承体系

  applicationContext:接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean对象

2、ApplicationContext的实现类

1、ClassPathXmlApplicationContext:
	从类的根路径下加载配置文件推荐使用
2、FileSystemXmlApplicationContext:
	从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
3、AnnotationConfigApplicationContext:
	使用注解配置容器对象时,需要使用此类来创建spring容器。它用来读取注解

3、getBean()方法使用

【框架】---->Spring 01 (IOC的实现)_第17张图片
在这里插入图片描述
如果有多个相同Bean时用id的方式,如果只有一个Bean时用Class方式。

【框架】---->Spring 01 (IOC的实现)_第18张图片

六、Spring的优势

1、方便解耦,简化开发
	通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度耦合。用户也不必在为单例模式类、属性文件解析等这些很底层的需求代码,可以专注于上层应用
2、AOP编程的支持
	通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松实现
3、声明式事务的支持
	可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式进行事务管理,提高开发效率好质量
4、方便程序的测试
	可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情
5、方便集成各种优秀框架
	Spring对各种优秀框架的支持
6、降低JavaEE API的使用难度
	Spring对JavaEE API进行了封装,使这些API的使用难度大为降低
7、Java源码是经典学习范例

你可能感兴趣的:(JavaWeb,spring,java,java-ee)