spring框架bean注入


今天学习了spring框架,刚刚入门简单的了解了spring并学习了bean的注入IOC:IOC(Inversion of Control,控制反转)不是什么技术,而是一种设计思想。它的目的是指导我们设计出更加松耦合的程序。

引入:

  使用简单代码来实现推演  ,创建一个maven项目,开始我们的推演   

创建一个bean类即常说的实体类如下:

 我们创建一个测试类 springTest,在测试类中操作,怎么样来获取Student类中 的信息呢(student类中有构造方法,无参,有参,有get,set方法,有studay() 方法 等等)

我们要怎么样来获取对象呢:

1.直接获取:

    @Test
    public void springTest() {
        Student student = new Student();
        student.getStudy();
        /*
        *  输出  学生在学习
        * */
    }

上述代码是否显得太low了,因为假若有n个类使用这个对像,我们要在每一个类中new,假若你要修改,这样的一个工程量会有点大。

2.工具类获取:

 我们创建工具类来减少耦合性,在修改维护时只要修改工具类就行 代码调用:

  @Test
    public void springTest02() {
        Student stu = StudentBean.getStu();
        stu.getStudy();
        /*
         *  输出  学生在学习
         * */
    }

这样就减少了一定的耦合性能,但在实际运用中,我们只可能只有一个实体类嘛当然不可能,如何提升性能并减少代码的耦合性呢

我们采用配置文件的方法建一个 beans.properties 存放bean的配置文件,并多创建一个实体类user

 重新再创建一个工具类BeanFactroy来编写我们的最终代码:

public class BeanFactory {
    //    创建map集合存储对象
    private static Map beanMap = new HashMap();

    /*
     *   在类初始化时读取beans配置文件中所有的bean类存储到map集合中
     * */
    static {
        try {
            ResourceBundle beans = ResourceBundle.getBundle("beans");// 读取beans配置文件
            Enumeration keys = beans.getKeys();  // 获取所有key值
            while (keys.hasMoreElements()) {
                String key = keys.nextElement();   // 获取每个key
                String className = beans.getString(key);  // 获取value
                Class<?> aClass = Class.forName(className);  // 通过反射得到该类
                Object o = aClass.newInstance();   // 通过反射机制创建该类对象
                beanMap.put(key, o);    // 将k v值存入beanMap集合中
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /* 创建静态方法供外界调用
    * */
    public static Object getBean(String beanName) {
        return beanMap.get(beanName);
    }
}

上面是工具类,下面是测试:

@Test
    public void springTest03() {
        User user = (User) BeanFactory.getBean("user");
        user.getStudy();
        /*
         *  输出  我在学习
         * */
    }
    @Test
    public void springTest04() {
        Student stu = (Student) BeanFactory.getBean("student");
        stu.getStudy();
        /*
         *  输出  学生在学习
         * */
    }

上面的实例简单的展示来如何减少耦合性,最终下来,在管理对象时,我们只需要修改beans.properties 文件即可,更加方便管理下面进入spring的ioc容器使用

Bean容器注入:

第一步导包:

<properties>
        <spring.version>5.2.9.RELEASEspring.version>
        <junit-version>5.6.2junit-version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>${spring.version}version>
        dependency>

        <dependency>
            <groupId>org.junit.jupitergroupId>
            <artifactId>junit-jupiterartifactId>
            <version>${junit-version}version>
        dependency>
    dependencies>

第二步创建配置文件 applicationContext.xml  (认准下面的步骤)

 完成后如下:

开始编写:

通过构造方法获取对象:

 测试代码:

    /*
     *  读取app.xml文件  抽取出来
     *  */
    private ApplicationContext ac = new ClassPathXmlApplicationContext("app.xml");

    @Test
    public void springTest05() {
        User user1 = (User) ac.getBean("user1");  // user1与app.xml中bean里面的id值相对应
        user1.getStudy();
        //  打印  我在学习
    }

读取xml方法:

  • ClassPathXmlApplicationContext: 从classpath目录读取配置文件
  • FileSystemXmlApplicationContext: 从文件系统或者url中读取配置文件
  • AnnotationConfigApplicationContext:当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器,它用来读取注解。  

使用前面的工厂来获取对象:

 测试代码:

    @Test
    public void springTest06() {
        User user1 = (User) ac.getBean("user2");  // user1与app.xml中bean里面的id值相对应
        user1.getStudy();
        //  打印  我在学习
    }

在操作这里的时候我将BeanFactory修改了一点:

public class BeanFactory {
    private String beanName;
    private static Map beansObjectHashMap = new HashMap();

    public BeanFactory() {
    }

    public BeanFactory(String beanName) {
        this.beanName = beanName;
    }

    /*
     * 采用静态代码块,在程序开始时,就将所有的对象存在beansObjectHashMap map集合中,使用时直接调用
     * */
    static {
        try {
            ResourceBundle beans = ResourceBundle.getBundle("beans");
            Enumeration keys = beans.getKeys();
            while (keys.hasMoreElements()) {
                String key = keys.nextElement();
                String className = beans.getString(key);
                Class<?> aClass = Class.forName(className);
                Object o = aClass.newInstance();
                beansObjectHashMap.put(key, o);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //    采用配置文件获取对象 只能 获取一个
    public static Object getBeanUser(String beanName) {
        try {
            ResourceBundle bundle = ResourceBundle.getBundle("beans");
            String string = bundle.getString(beanName);
            Class<?> aClass = Class.forName(string);
            Object o = aClass.newInstance();
            return o;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /*
     *   当有多个实体类时  封装一个map集合返回
     * */
    public static Object getBeanMap(String beanName) {
        return beansObjectHashMap.get(beanName);
    }
 /*   public Object getBeanMap() {
        return beansObjectHashMap.get(this.beanName);
    }*/
}

Bean单例与多例:

    
    <bean id="user3" class="com.code.spring01.entity.User" scope="singleton">bean>  
    <bean id="user4" class="com.code.spring01.entity.User" scope="prototype">bean>  
    

set方法注入:

 
    <bean id="stu2" class="com.code.spring01.entity.Student">
        <property name="age" value="19">property>
        <property name="name" value="张三">property>
    bean>
    
    
    <bean id="stu3" class="com.code.spring01.entity.Student" p:name="王五" p:pwd="123" p:age="31" p:sex="男"/>

集合属性注入:

实体类:

public class Tec {
    // 基本属性
    private Integer id;
    private String username;
    private String password;
    private Address address;
    //list  set   array
    private String[] str;
    private List list;
    private Set set;

    //map  properties
    private Map map;
    private Properties properties;
    
    // 省略了set方法

bean注入:

<bean id="user" class="com.hopu.ioc.User">
        <property name="str">
            <array>
                <value>EEvalue>
                <value>FFvalue>
            array>
        property>
        <property name="list">
            <list>
                <value>AAvalue>
                <value>BBvalue>
            list>
        property>
        <property name="set">
            <set>
                <value>CCvalue>
                <value>DDvalue>
            set>
        property>

        <property name="map">
            <map>
                <entry key="GG" value="gg"/>
                <entry key="HH" value="hh"/>
            map>
        property>
        <property name="properties">
            <props>
                <prop key="II">iiprop>
                <prop key="JJ">jjprop>
            props>
        property>
    bean>

Bean的多模块注入:

当项目过于庞大时,为了开发便于维护和可读性,我们可以将bean配置文件模块化,采用导入模块方式优化管理

   
    <import resource="app2.xml"/>

注解注入:

这个我没学,在百度上看了,简单模仿这操作一番:

@Component("admin")  // 等同于bean id="admin" class="com.code.spring01.entity.Admin">
@Scope(scopeName = "singleton")  // 限制创建的为单例对象
//@Scope(scopeName = "prototype")  // 限制创建的为多例对象
//@Component("id") 取代
public class Admin { private String name; private String color; public Admin(String name, String color) { this.name = name; this.color = color; } public Admin() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return color; } public void setAge(String color) { this.color = color; } @Override public String toString() { return "Admin{" + "name='" + name + '\'' + ", color='" + color + '\'' + '}'; } }

私有成员变量注入:

    @Value("BMW")
    private String name;
    @Value("Red")
    private String color;

set方法注入:

 @Value("BMW")
    public void setName(String name) {
        this.name = name;
    }
    @Value("Red")
    public void setColor(String color) {
        this.color = color;
    }    

个人学习,内容简略。