• Spring框架配置beans.xml扩展


    Spring学习笔记(二)

    续Spring 学习笔记(一)之后,对Spring框架XML的操作进行整理

    1 什么是IOC(DI)

     IOC = inversion of control   控制反转

     DI   = dependency injection 依赖注入

    2 个人理解IOC(DI)的好处和作用

    本来自己在代码NEW的东西改为由Spring来管理,体现了控制方的转变。

    在由Spring管理的时候,需要用户通过配置bean来实现bean与bean的关联,依赖/注入为配置的方式,

    好处何作用---》只需要管理配置文件就可以对类的进行管理-->灵活,可阅读性强。

    本次笔记中的Spring的常用配置说明目录

    1 Spring的注入类型

    2 简单的属性注入

    3 scope属性 

    4 集合注入MAP,SET,LIST

    5 自动装配 autowire

    6 生命周期lazy-init  和初始毁灭方法的调用 init-method,destroy-method 

    3 Spring 的注入类型

    a setter注入(笔记一里已经实现,不再累述)

    b 构造方法注入(沿用笔记一里的文件进行修改)

    UserServiceImpl 类(存在构造函数)

    package com.serviceImpl;
    
    import com.dao.UserDao;
    import com.daoImpl.UserDaoImpl;
    import com.entity.User;
    
    public class UserServiceImpl {
        private UserDao userDao;
    
        UserServiceImpl(UserDao userDao){//构造函数
            this.userDao = userDao;
        }
        
        public void add(User user) {
            userDao.save(user);
        }
    
        public void modify(User user) {
            userDao.update(user);
        }
    
        public UserDao getUserDao() {
            return userDao;
        }
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    }

    beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">
      </bean>
      
      <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
      </bean>
      
      <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl">
         <constructor-arg><ref bean="userDaoImpl"/></constructor-arg>   <!-- 构造函数的注入配置-->
      </bean>
    </beans>

    执行UserServiceImplTest文件(无任何改动)

    执行结果

    testName-->testRemark  save --调用UserDaoImpl!

    testName-->testRemark  update --调用UserDaoImpl!

    总结,构造方法与setter方法注入实现起来差不多,只是调用的bean里面内部的标签不同而已

    4 bean 标签里 使用Id和name的区别,这个不做研究了,查看了下文档,name只可以输入特殊字符"@#!@$!",没什么区别。

    4 简单的属性注入

    UserServiceImpl里面有个int类型的变量testInjectValue 未赋值

    package com.serviceImpl;
    
    import com.dao.UserDao;
    import com.daoImpl.UserDaoImpl;
    import com.entity.User;
    
    public class UserServiceImpl {
        private UserDao userDao;
        int testInjectValue;//简单属性注入的测试
    
        UserServiceImpl(UserDao userDao){
            this.userDao = userDao;
        }
        
        public void add(User user) {
            userDao.save(user);
            System.out.println("testInjectValue = "+testInjectValue);
        }
    
        public void modify(User user) {
            userDao.update(user);
            System.out.println("testInjectValue = "+testInjectValue);
        }
    
        public UserDao getUserDao() {
            return userDao;
        }
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public int getTestInjectValue() {
            return testInjectValue;
        }
    
        public void setTestInjectValue(int testInjectValue) {
            this.testInjectValue = testInjectValue;
        }
        
    }

    我们通过beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">
      </bean>
      
      <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
      </bean>
      
      <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl">
         <constructor-arg><ref bean="userDaoImpl"/></constructor-arg> 
         <property name="testInjectValue" value="34"></property>  <!--简单属性的注入-->
      </bean>
    </beans>

    执行测试文件

    执行结果

    testName-->testRemark save --调用UserDaoImpl!
    testInjectValue = 34

    testName-->testRemark update --调用UserDaoImpl!
    testInjectValue = 34

    总结.与接口的setter注入差不多,只是接口对应的是 bean="beanName", 这里是value="value"

    5 bean里面的scope属性的运用

    1 scope=singleton

    beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">
      </bean>
      
      <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
      </bean>
      
      <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl" scope="singleton"> <!-- 添加配置scope="singleton"-->
         <constructor-arg><ref bean="userDaoImpl"/></constructor-arg> 
      </bean>
    </beans>

    2 scope=prototype

    beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">
      </bean>
      
      <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
      </bean>
      
      <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl" scope="prototype"> <!-- 添加配置scope="prototype"-->
         <constructor-arg><ref bean="userDaoImpl"/></constructor-arg> 
      </bean>
    </beans>

    3 分别配置scope=prototype/singleton和不配置scope 并执行UserServiceImplTest文件并查看结果

    package com.serviceImpl.test;
    
    import static org.junit.Assert.*;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.entity.User;
    import com.serviceImpl.UserServiceImpl;
    
    public class UserServiceImplTest {
        User user;
    
        @Before
        public void setUp() throws Exception {
            user = new User();
            user.setName("testName");
            user.setRemark("testRemark");
        }
    
        @Test
        public void testAdd() {
             ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
             UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
             UserServiceImpl UserServiceImpl2 = (UserServiceImpl)app.getBean("userServiceImpl");
             System.out.println(UserServiceImpl==UserServiceImpl2);
    //         UserServiceImpl.add(user);//调用方法
        }
    
        @Test
        public void testModify() {
             ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
             UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
             UserServiceImpl UserServiceImpl2 = (UserServiceImpl)app.getBean("userServiceImpl");
             System.out.print(UserServiceImpl==UserServiceImpl2);
    //         UserServiceImpl.modify(user);
        }
    }

    当scope=singleton时 执行结果为 true true

    当scope=prototype时 执行结果为false false

    当不配置scope时         执行结果为true true

    总结 scope不做定义时,spring默认类的实现方式是为单例模式

    只有scope=prototype时,spring会在每次调用时都去重新NEW一个新的类

    6集合注入

    UserServiceImpl 

    package com.serviceImpl;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import com.dao.UserDao;
    import com.daoImpl.UserDaoImpl;
    import com.entity.User;
    
    public class UserServiceImpl {
        private UserDao userDao;
        
        Map testMap;
        Set testSet;
        List testList;
    
        public void add(User user) {
            userDao.save(user);
            System.out.println(testMap.get("m"));
            System.out.println(testSet.iterator());
            System.out.println(testList.get(0));
        }
    
        public UserDao getUserDao() {
            return userDao;
        }
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public Map getTestMap() {
            return testMap;
        }
    
        public void setTestMap(Map testMap) {
            this.testMap = testMap;
        }
    
        public Set getTestSet() {
            return testSet;
        }
    
        public void setTestSet(Set testSet) {
            this.testSet = testSet;
        }
    
        public List getTestList() {
            return testList;
        }
    
        public void setTestList(List testList) {
            this.testList = testList;
        }
    }

    beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">
        </bean>
    
        <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
        </bean>
    
        <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl">
            <property name="userDao" ref="userDaoImpl"></property>
            <property name="testList">
                <list>
                    <value>inject list</value>
                </list>
            </property>
    
            <property name="testMap">
                <map>
                    <entry key="m" value="inject map" />
                </map>
            </property>
            <property name="testSet">
                <set>
                    <value>inject set</value>
                </set>
            </property>
        </bean>
    </beans>

    执行UserServiceImplTest文件

    执行结果

    testName-->testRemark save --调用UserDaoImpl!
    inject map
    java.util.LinkedHashMap$KeyIterator@435a3a
    inject list

    总结 

    1 这个还是和之前的注入差不多,要用的时候看一眼说明书即可。

    7  自动装配(不是很常用)

    autowire="byName"(不在代码实现了,用byType抛砖引玉)

    autowire="byType"(注意:spring如果找到一个以上的具有同类型的bean会报错,所以我这里注释了userDaoImpl的bean)

    beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">-->
    <!--    </bean>-->
    
        <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
        </bean>
    
        <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl" autowire="byType">
    <!--        <property name="userDao" ref="userDaoImpl"></property>-->
        </bean>
    </beans>

    执行UserServiceImplTest文件

    执行结果

    testName-->testRemark  save --调用UserDaoImpl2!

    总结

    1 这个功能点不是很重要,按类型的话很多bean可能会起冲突,如果按名字的话,又对名字有很高的匹配要求,所以不是很实用。

    2 另外在头部配置 autowire 的默认值后,可以使用beans的属性:default-autowire (基于这个功能不是很实用,所以没去试过)。

    8 生命周期(配置bean的初始策略)

     lazy-init 

    当不配置lazy-init=true时 applicationcontext被NEW出来的时候,所有的bean都会被初始化。

    当配置了,这个bean就不会被初始化,除非方法调用。(系统启动特别慢时,可以考虑lazy-init =true 不然没什么太大意义

     init-method destroy-methd 方法的使用

    beans.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="userDaoImpl" class="com.daoImpl.UserDaoImpl">
        </bean>
    
        <bean id="userDaoImpl2" class="com.daoImpl.UserDaoImpl2">
        </bean>
    
        <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl" init-method="init" destroy-method="destroy" lazy-init="true">
            <property name="userDao" ref="userDaoImpl"></property>
        </bean>
    </beans>

    UserServiceImpl

    package com.serviceImpl;
    
    
    import com.dao.UserDao;
    import com.daoImpl.UserDaoImpl;
    import com.entity.User;
    
    public class UserServiceImpl {
        private UserDao userDao;
    
        public void add(User user) {
            userDao.save(user);
        }
        
        public void init(){//初始方法
            System.out.println("init");
        }
    
        public void destroy(){//销毁方法
            System.out.println("destory");
        }
    
        public UserDao getUserDao() {
            return userDao;
        }
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
        
    }

    UserServiceImplTest

    package com.serviceImpl.test;
    
    import static org.junit.Assert.*;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.entity.User;
    import com.serviceImpl.UserServiceImpl;
    
    public class UserServiceImplTest {
        User user;
    
        @Before
        public void setUp() throws Exception {
            user = new User();
            user.setName("testName");
            user.setRemark("testRemark");
        }
    
        @Test
        public void testAdd() {
            ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
             UserServiceImpl UserServiceImpl = (UserServiceImpl)app.getBean("userServiceImpl");
             UserServiceImpl UserServiceImpl1 = (UserServiceImpl)app.getBean("userServiceImpl");
             UserServiceImpl.add(user);//调用方法
             app.destroy();//在WEB应用里会自动调用,这里直接手动调用了。
        }
    
    }

    执行UserServiceImplTest文件

    执行结果

    init
    testName-->testRemark save --调用UserDaoImpl!

    destory

    总结

     init-method destroy-methd 方法的使用需要注意别与scope=prototype并用,用上面的代码测试了一下,结果是init被调用了2次,但是destroy未被调用过,不解。

    结束总结

    Spring配置文件提供了以下的配置手法及管理策略,对项目的管理能有不少的帮助,学习下来较为实用的还是setter注入。

    1 Spring的注入类型

    2 简单的属性注入

    3 scope属性 

    4 集合注入MAP,SET,LIST

    5 自动装配 autowire

    6 生命周期lazy-init  和初始毁灭方法的调用 init-method,destroy-method 

  • 相关阅读:
    hugo博客使用 utterances 作为评论系统
    使用DEM生成彩色的立体图像
    hibernate Annotation 注解形式 实例 事务 hibernate.cfg.xml
    web.xml配置webAppRootKey 的问题
    JAVA 生成二维码 代码
    关于Boost库的split函数在不同的编译器下的使用
    纯 hibernate hibernate.cfg.xml 事务 数据库操作 CRUD
    Android 百度地图API 定位 导航 代码
    Android GPS
    使用GDAL对DEM进行彩色渲染
  • 原文地址:https://www.cnblogs.com/sunfan1988/p/3464306.html
Copyright © 2020-2023  润新知