• spring_装配Bean


    Spring容器:

    Spring有两种不同的容器,一个是org.springframework.beans.factory.BeanFactory接口实现,另一个是应用上下文org.springframework.context.ApplicationContext接口实现.

    BeanFactory是简单的容器,提供了基础的依赖注入,ApplicationContext是建立在BeanFactory基础之上的,它是Beanfactory的子类,功能比BeanFactory更加强大。

    ApplicationContext提供了更多功能:

    • 提供了文本信息解析工具,包括对国际化的支持
    • 提供了载入文件资源的通用方法,如载入图片
    • 可以向注册为监听器的Bean发送事件

    ApplicationContext经常用到的三种实现:ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, XmlWebApplicationContext

    使用BeanFactory示例:

    1         BeanFactory factory = new XmlBeanFactory(new ClassPathResource(
    2                 "beans.xml"));
    3         UserSave usersave = (UserSave) factory.getBean("usersave");

    使用ApplicationContext示例:

    1         ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    2         UserSave usersave = (UserSave) context.getBean("usersave");

    Bean的作用域:

    作用域

    描述

    singleton

    在每个Spring IoC容器中一个bean定义对应一个对象实例。

     

    prototype

    一个bean定义对应多个对象实例。

     

    request

    在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。

     

    session

    在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

     

    global session

    在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

     

    示例:在beans.xml中

    1     <bean id="usersave" class="com.yuan.test.UserSave" scope="singleton">
    2         <property name="user">
    3             <ref bean="user" />
    4         </property>
    5     </bean>

    第1行中scope属性定义bean的作用域,将其定义为singleton即为单例。下面代码输出为true

    1 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    2         
    3         UserSave usersave = (UserSave) context.getBean("usersave");
    4         UserSave usersave2 = (UserSave) context.getBean("usersave");
    5         
    6         System.out.println(usersave == usersave2);

    同样可以测试其他的属性值。

    依赖注入的方法:

    1. 接口注入
    2. 构造注入
    3. 设值注入

    接口注入是要自定义的Bean实现规定的接口,Spring会自动进行注入,一般用的很少,下面是构造注入和设值注入的示例:

    设值注入:

    在Bean中为属性设置setter方法。

     1 public class UserSave {
     2     private User user;
     3 
     4     public User getUser() {
     5         return user;
     6     }
     7 
     8     public void setUser(User user) {
     9         this.user = user;
    10     }
    11 
    12     public void saveUser() {
    13         System.out.println("user saved!");
    14     }
    15 }

    然后在配置文件中设置对应<property>元素并指定初值,如下第4~6行中引用外部bean作为初值

    1     <bean id="user" class="com.yuan.test.User"></bean>
    2 
    3     <bean id="usersave" class="com.yuan.test.UserSave" scope="singleton">
    4         <property name="user">
    5             <ref bean="user" />
    6         </property>
    7     </bean>

    构造注入:

    为bean提供构造函数。

    1 public class UserSave {
    2     private User user;
    3 
    4     public UserSave(User user) {
    5         this.user = user;
    6     }
    7 }

    修改配置文件,在<constructor-arg>中设置初值

    1     <bean id="usersave" class="com.yuan.test.UserSave" scope="singleton">
    2         <constructor-arg>
    3             <ref bean="user" />
    4         </constructor-arg>
    5     </bean>

    构造注入在有些情况下会遇到些问题,如果有多个参数,我们可以依据类型依次设置配置文件中的参数值,也可以调换顺序,不过要让Spring知道

     1 public class Student {
     2     private String arg1;
     3     private URL arg2;
     4 
     5     public Student(String arg1, URL arg2) {
     6         this.arg1 = arg1;
     7         this.arg2 = arg2;
     8     }
     9 
    10 }

     如下是按照顺序,http://www.baidu.com赋给第一个参数arg1, http://www.google.com赋给第二参数。

    1 <bean id="student" class="com.yuan.test.Student">
    2         <constructor-arg>
    3             <value>http://www.baidu.com</value>
    4         </constructor-arg>
    5         <constructor-arg>
    6             <value>http://www.google.com</value>
    7         </constructor-arg>
    8     </bean>

    也可以是随便编写参数的位置,不过要在属性中指定对应的参数位置,如下:

    1 <bean id="student" class="com.yuan.test.Student">
    2         <constructor-arg index="1">
    3             <value>http://www.baidu.com</value>
    4         </constructor-arg>
    5         <constructor-arg index="0">
    6             <value>http://www.google.com</value>
    7         </constructor-arg>
    8     </bean>

    在<constructor-arg>元素中加了index属性,设置对应构造函数中的参数位置。这里http://www.baidu.com赋给arg2, http://www.google.com赋给arg1

    1 <bean id="student" class="com.yuan.test.Student">
    2         <constructor-arg type="java.net.URL">
    3             <value>http://www.baidu.com</value>
    4         </constructor-arg>
    5         <constructor-arg type="java.lang.String">
    6             <value>http://www.google.com</value>
    7         </constructor-arg>
    8     </bean>

    如上,也可以通过type属性设置对应构造函数中的参数类型,不过如果构造函数中有相同的类型参数,这种方法不可取。

     

    自动装配:

    关于自动装配,个人觉得不够细粒度,如果为了系统稳定最好还是手工编写好。可以参考文章:了解Spring自动装配

     

    Spring中特殊的Bean:

    参考文章:Spring笔记 (2) 特殊Bean

    分散配置:

    在项目开发中,有时候要从一些配置文件中(properties)读取一些配置信息,如数据库的连接信息。在Spring程序中可以从不同的properties中读取有用的信息。这里要用到org.springframeword.beans.factory.config.PropertyPlaceholderConfigurer类,它是BeanFactoryPostProcessor的实现类.

    下面例子:

    项目结构:

    connet.properties:

    driver=mysql
    username=yuan
    password=test

    test.properties:

    1 age=12
    2 height=13
    3 weight=14

    Connect.java装载着两个properties的信息:

    public class Connect {
        private String driver;
        private String username;
        private String password;
        int age;
        int height;
        int weight;
            //省略getter,setter    
    }

    beans.xml:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
     5 
     6     <bean id="propertyConfigurer"
     7         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     8         <property name="locations">
     9             <list>
    10                 <value>connect.properties</value>
    11                 <value>test.properties</value>
    12             </list>
    13         </property>
    14     </bean>
    15     
    16     <bean id="connect" class="com.sunflower.yuan.Connect">
    17         <property name="driver">
    18             <value>${driver}</value>
    19         </property>
    20         
    21         <property name="username">
    22             <value>${username}</value>
    23         </property>
    24         
    25         <property name="password">
    26             <value>${password}</value>
    27         </property>
    28         
    29         <property name="age">
    30             <value>${age}</value>
    31         </property>
    32         
    33         <property name="height">
    34             <value>${height}</value>
    35         </property>
    36         
    37         
    38         <property name="weight">
    39             <value>${weight}</value>
    40         </property>
    41     </bean>
    42 
    43 </beans>

     第6~14行中,<properties name="locations">标签里面指定要读取的properties文件的位置。16~41行中用EL表达式将预先加载的properties属性注入到Bean中

     测试类Test.java:

    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    "beans.xml");
    
            Connect source = (Connect) context.getBean("connect");
    
            String username = source.getUsername();
            String password = source.getPassword();
            int age = source.getAge();
            int weight = source.getWeight();
            int height = source.getHeight();
    
            System.out.println("username is:" + username + " password is:"
                    + password);
            System.out.println("age is:" + age + " weight is:" + weight
                    + " height is:" + height);
        }
    }

    运行结果:

     

    一颗平常心,踏踏实实,平静对待一切
  • 相关阅读:
    POJ 题目2750 Potted Flower(线段树求环型区间中连续区间的最大和)
    即使没人看我们也要坚持写Blog
    鸟哥的Linux私房菜-----7、硬件管理
    android createbitmap函数内存溢出,求解怎样进行处理out of memory溢出问题
    hdu4614Vases and Flowers 线段树
    安装npm及cnpm(Windows)
    安装npm及cnpm(Windows)
    安装npm及cnpm(Windows)
    Echarts设置点击事件
    Vs Code中炫酷写代码插件Power Mode的安装配置
  • 原文地址:https://www.cnblogs.com/hanyuan/p/2690549.html
Copyright © 2020-2023  润新知