ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring系统学习--1、IOC和DI

2020-07-01 23:04:19  阅读:265  来源: 互联网

标签:DI IAccountService Spring void class bean context IOC public


Spring,Spring,Spring,天天用,但是对她太过缺乏“深入”的了解,今天思虑良久,下定决心,我要好好“深入的”了解一下她。

Spring是一个架构性的框架:也就是改变代码结构的框架;

1.学习环境的准备

大部分教学视频是使用老掉牙Ecliplse教学Spring的,但是我TM是真的不想用Ecliplse,虽然我电脑上有Ecliplse...如果你要选择Ecliplse那么你可以跟着视频老老实实创建java项目--->导入jar包--->创建XML配置文件,完成spring学习环境的搭建;但是下面我要说的是我是如何使用IDEA开始Spring的学习的:

 

 

 

 

 

 创建完maven项目之后,在pom.xml文件里面添加如下依赖:
<!--  spring-context:导入spring核心jar包  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.7.RELEASE</version>
<!--      <scope>test</scope>-->
    </dependency>
<!--    导入日志jar包-->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>
  </dependencies>

然后,你会发现项目依赖库下面增加了许多spring相关jar:

 

然后我们在项目资源文件夹src下面创建spring的配置文件:

 这样你就可以愉快的开始spring学习之旅了....简单吧

2.IOC入门案例

2.1在bean.xml里面添加如下配置:

前提是下面的类已经在对应的路径下创建了:

<!--
bean:来映射一个类
id:是bean的唯一标识,如果没有指定则默认将会以类名作为标识
class:映射类的全路径
IOC容器管理默认是单例
-->
<bean id="accountService" class="main.java.service.impl.IAccountServiceImpl"></bean>
<bean id="accountDao" class="main.java.dao.impl.IAccountDaoImpl"></bean>

 

 

 2.2获取Spring的核心容器,并且根据bean的id获取对象

创建一个类,书写如下代码:

public class Client {
    public static void main(String[] args) {
        /**
         * 获取Spring的核心容器,并且根据bean的id获取对象
         *
         * ApplicationContext:是BeanFactory的孙子接口,创建对象的时候采取的是理解加载的策略.(读取完XML配置文件之后,xml里面所有的bean对象就已经全部创建完成了)
         */
//        1.获取容器
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//        2.根据bean的id获取对象
        IAccountService iAccountService=(IAccountService)context.getBean("accountService");
        IAccountDao accountDao = context.getBean("accountDao", IAccountDao.class);
        System.out.println(iAccountService);
        System.out.println(accountDao);
    }
}

补充:ApplicationContext子类:

       /* * ApplicationContext子类:
         * -----ClassPathXmlApplicationContext:
         *      她是通过读取类路径下的配置文件创建spring容器;要求配置文件在类路径下
         * -----FileSystemXmlApplicationContext
         *      她是通过读取文件系统中的配置文件创建spring容器;要求配置文件在文件系统中即可
         */

 

2.3懒加载

如果我ლ❥们xml文件里面bean非常多,在创建容器的时候我们瞬间初始化那么多bean可能会导致卡顿,这个时候我们可以在xml文件里面按照下图:就能实现在调用getBean时才初始化:

 

 

 2.4懒加载容器

如果我们不想通过上面的配置实现懒加载,下面的代码也可以实现在getBean时才创建对象:

public class Client {
    public static void main(String[] args) {
        /**
         * 获取Spring的核心容器,并且根据bean的id获取对象
         *
         * ApplicationContext:是BeanFactory的孙子接口,创建对象的时候采取的是理解加载的策略.(读取完XML配置文件之后,xml里面所有的bean对象就已经全部创建完成了)
         * BeanFactory:是springIoc的顶层接口,创建bean对象时,采用延迟加载的策略(当真正要从容器中获取对象时,才会创建,读完配置文件并不创建)
         */
//        1.获取容器
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//        2.获取对象
        IAccountService iAccountService = (IAccountService) context.getBean("accountService");
        IAccountDao accountDao = context.getBean("accountDao", IAccountDao.class);
        System.out.println(iAccountService);
        System.out.println(accountDao);

//        1.加载配置文件
        Resource resource = new ClassPathResource("bean.xml");
//        2.获取容器
        BeanFactory beanFactory = new XmlBeanFactory(resource);
//        3.获取对象
        IAccountService accountService = beanFactory.getBean("accountService", IAccountService.class);
    }
}

2.5bean对象的三种创建方式

<?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"
><!--default-lazy-init="true" :设置所有的bean为懒加载 -->

<!--spring管理bean对象细节:
bean标签:来映射一个类
    作用:让spring帮我们读取配置之后创建对象
    属性:
        id:是bean的唯一标识,如果没有指定则默认将会以类名作为标识
        class:映射类的全路径
        factory-method:指定创建bean对象的方法;
        factory-bean:指定创建bean对象的工厂bean的id

bean对象的三种创建方式:
                    1.通过调用默认构造函数创建bean对象   (常用)
                    在默认情况下我们在spring配置文件中写了一个bean标签,并提供了class属性,spring就会调用默认构造方法创建对象
                    2.通过静态工厂创建bean对象
                        工厂类中提供一个静态方法,可以返回一个我们要获取的类的对象
                        public class BeanFactory {
                                public static IAccountService getBean1() {
                                    return new IAccountServiceImpl();
                                 }
                                                  }
                    3.通过实例工厂创建bean对象
                         工厂类中提供一个非静态方法,可以返回一个我们要获取的类的对象
                         public class BeanFactory {
                                 public IAccountService getBean2() {
                                         return new IAccountServiceImpl();
                                 }
                                                   }
-->
<!--    1.默认方式创建对象:-->
<bean id="accountService" class="main.java.service.impl.IAccountServiceImpl"></bean>
<!--    2.静态工厂创建对象
                        id:bean的id
                        class:工厂类
                        factory-method:工厂类里面生成bean对象的方法(静态方法)
-->
    <bean id="staticFactory" class="main.java.factory.BeanFactory" factory-method="getBean1"></bean>

<!--    3.实例工厂创建对象
                        factory-bean:指定工厂bean的id
                        factory-method:指定工厂类里面生产bean对象的方法(非静态方法)
-->
    <bean id="instanceFactory" class="main.java.factory.BeanFactory"></bean>
    <bean id="instanceFactoryBean" factory-bean="instanceFactory" factory-method="getBean2"></bean>
</beans>
public class CreatBeanTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//        1.默认构造函数创建对象,获取方法
        IAccountService accountService = context.getBean("accountService", IAccountService.class);
        System.out.println(accountService);//main.java.service.impl.IAccountServiceImpl@17f7cd29
//        2.静态工厂创建对象,获取方法
        IAccountService accountService1 = context.getBean("staticFactory", IAccountService.class);
        System.out.println(accountService1);//main.java.service.impl.IAccountServiceImpl@7d8704ef
//        3.实例工厂创建对象,获取方法
        IAccountService accountService2 = context.getBean("instanceFactoryBean", IAccountService.class);
        System.out.println(accountService2);//main.java.service.impl.IAccountServiceImpl@17f7cd29
    }
}

2.6bean对象的作用范围:

<!--
bean对象的作用范围:
    它是可以通过配置的方式来指定的。
    配置的属性:bean标签的scope属性
    属性的取值:
        singleton:单例的。默认值
        prototype:多例的.
        request:WEB项目中,Spring创建一个Bean的对象,将对象存入到 request域中。
        session:WEB项目中,Spring创建一个Bean的对象,将对象存入到 session域中。
        global-session:WEB项目中,应用在 Portlet环境,如果没有Portlet环境那么 global-session相当于session

-->
<bean id="accountService" class="main.java.service.impl.IAccountServiceImpl" scope="prototype"></bean>

2.7bean对象的生命周期:

<!--
bean对象的生命周期:
    单例对象
        出生:容器创建对象出生
        活着:只要容器存在,对象就一直可用。
        死亡:容器销毁,对象消亡。
    多例对象
        出生:每次使用时,容器会为我们创建对象。
        活着:只要对象在使用过程中,就一直活着。
        死亡:当对象长时间不用,并且也没有其他对象引用时,由java的垃圾回收器回收.
-->
<bean id="singleton_accountService" class="main.java.service.impl.IAccountServiceImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>
<bean id="prototype_accountService" class="main.java.service.impl.IAccountServiceImpl" scope="prototype" init-method="init" destroy-method="destory"></bean>
public class IAccountServiceImpl  implements IAccountService {
    IAccountDao iAccountDao=new IAccountDaoImpl();
    public IAccountServiceImpl(){
        System.out.println("对象创建了!!!");
    }
    public void init(){
        System.out.println("对象初始化了");
    }
    public void destory(){
        System.out.println("对象销毁了了");
    }
    @Override
    public void saveAccount() {
        iAccountDao.save();
    }
}
public class _05LifecycleTest {
    public static void main(String[] args) {
//        1.获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean_lifecycle.xml");
//        2.获取对象
        IAccountService accountService1 = context.getBean("singleton_accountService", IAccountService.class);
        System.out.println(accountService1);
        IAccountService accountService2 = context.getBean("prototype_accountService", IAccountService.class);
        System.out.println(accountService2);
//        3.销毁容器
        context.close();
    }
}

3.DI依赖注入

3.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--
Spring的依赖注入
    注入的方式:只有3中(今天只涉及两种)
                第一种方式:通过构造函数注入
                第二种方式:通过set方法注入
    注入的内容:
                第一类:基本类型和String类型
                第二类:其他的bean类型
                第三类:复杂类型(集合类型)
-->
<!--
第一种:使用构造函数注入:
            该方式要求对应的类必须有对应的带参构造方法
            涉及的标签:
            constructor-arg
            该标签是写在bean标签内部的子标签
            标签的属性:
                type:指定要注入的参数在构造函数中的类型
                index:指定要注入的参数在构造函数的索引位置
                name:指定参数在构造函数的中的名称
                value:指定注入的数据内容,他只能指定基本类型数据和String类型数据
                ref:指定其他bean类型数据。写的是其他bean的id。其他bean指的是存在于spring容器中的bean。
-->
<!--    1.构造方法注入-->
<bean id="accountService" class="main.java.service.impl.IAccountServiceImpl" >
    <constructor-arg name="name" value="李沁"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
<!--
第二种:使用set方法注入常用
            涉及的标签:
            property
            该标签也是要写在bean标签内部的子标签
            标签的属性:
                name:指定的是set方法的名称。匹配的是类中set后面的部分的全小写。
                value:指定注入的数据内容,他只能指定基本类型数据和String类型数据
                ref:指定其他bean类型数据。写的是其他bean的id。其他bean指的是存在于spring容器中的bean。
-->
<!--    2.set方法注入-->
    <bean id="accountService2" class="main.java.service.impl.IAccountServiceImpl" >
        <property name="name" value="李沁2"></property>
        <property name="age" value="17"></property>
        <property name="birthday" ref="birthday"></property>
    </bean>
</beans>
public class IAccountServiceImpl  implements IAccountService {
    private String name;
    private int age;
    private Date birthday;

    public IAccountServiceImpl(String name, int age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

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

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

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public IAccountServiceImpl(){
        System.out.println("对象创建了!!!");
    }
    @Override
    public void saveAccount() {
        System.out.println(name+age+birthday);
    }
}
public class _06DI {
    public static void main(String[] args) {
//        1.获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean_DI.xml");
//        2.获取对象
        IAccountService accountService1 = context.getBean("accountService", IAccountService.class);
        accountService1.saveAccount();
        IAccountService accountService2 = context.getBean("accountService2", IAccountService.class);
        accountService2.saveAccount();
//        3.销毁容器
        context.close();
    }
}

3.2  P名称空间注入:

<!--
使用p名称空间注入
    它的本质仍然是需要类中提供set方法,同时在配置文件中要导入p名称空间
-->
    <bean id="accountService3" class="main.java.service.impl.IAccountServiceImpl" p:name="李沁3">
    </bean>

 

 

 3.3特殊类型属性注入

public class CollectionsDI {
    private String [] strings;
    private List<String>myList;
    private Set<String> mySet;
    private Map<String,String>myMap;
    private Properties myProps;

    public void setStrings(String[] strings) {
        this.strings = strings;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }
    public void print(){
        System.out.println(Arrays.toString(strings));
        System.out.println(myList);
        System.out.println(myMap);
        System.out.println(mySet);
        System.out.println(myProps);
    }
}
<bean id="CollectionsDI" class="main.java.service.CollectionsDI" >
        <!-- 1.给数组注入数据-->
        <property name="strings">
            <array>
                <value>args</value>
                <value>args</value>
                <value>args</value>
            </array>
        </property>
        <!-- 2.给List注入数据-->
        <property name="myList">
            <list>
                <value>LIST</value>
                <value>LIST</value>
                <value>LIST</value>
            </list>
        </property>
        <!-- 3.给Set注入数据-->
        <property name="mySet">
            <set>
                <value>SET</value>
                <value>SET</value>
                <value>SET</value>
            </set>
        </property>
        <!-- 4.给Map注入数据-->
        <property name="myMap">
            <map>
                <entry key="001" value="map"></entry>
                <entry key="002">
                    <value>map注入方式2</value>
                </entry>
            </map>
        </property>
        <!-- 5.给Properties注入数据-->
        <property name="myProps">
            <props>
                <prop key="url">http:www.baidu.com</prop>
            </props>
        </property>
    </bean>
public class _06DI {
    public static void main(String[] args) {
//        1.获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean_DI.xml");
//        2.获取对象
        CollectionsDI collectionsdi = context.getBean("CollectionsDI", CollectionsDI.class);
        collectionsdi.print();
        /**
         [args, args, args]
         [LIST, LIST, LIST]
         {001=map, 002=map注入方式2}
         [SET1, SET2, SET3]
         {url=http:www.baidu.com}
         */
//        3.销毁容器
        context.close();
    }
}

注意:上面xml文件里面bean标签内部结构相同的标签可以互换使用:

 <!-- 1.给数组注入数据-->
        <property name="strings">
            <list>
                <value>LIST</value>
                <value>LIST</value>
                <value>LIST</value>
            </list>
        </property>
        <!-- 2.给List注入数据-->
        <property name="myList">
            <array>
                <value>args</value>
                <value>args</value>
                <value>args</value>
            </array>
        </property>    

3.4注入时特殊符号处理

 

 3.5

 

标签:DI,IAccountService,Spring,void,class,bean,context,IOC,public
来源: https://www.cnblogs.com/luzhanshi/p/11685763.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有