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<String, Object> beanMap = new HashMap<String, Object>();

    /*
     *   在类初始化时读取beans配置文件中所有的bean类存储到map集合中
     * */
    static {
        try {
            ResourceBundle beans = ResourceBundle.getBundle("beans");// 读取beans配置文件
            Enumeration<String> 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.RELEASE</spring.version>
        <junit-version>5.6.2</junit-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <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<String, Object> beansObjectHashMap = new HashMap<String, Object>();

    public BeanFactory() {
    }

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

    /*
     * 采用静态代码块,在程序开始时,就将所有的对象存在beansObjectHashMap map集合中,使用时直接调用
     * */
    static {
        try {
            ResourceBundle beans = ResourceBundle.getBundle("beans");
            Enumeration<String> 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单例与多例,在bean容器中添加有个scope属性,singleton代表单例
         prototype 代表多例,单例获取的对象地址值是相同的,多例是不同的
         调用案例就一样的不写了
    -->
    <bean id="user3" class="com.code.spring01.entity.User" scope="singleton"></bean>  <!-- 单例 -->
    <bean id="user4" class="com.code.spring01.entity.User" scope="prototype"></bean>  <!-- 多例 -->
    <!--
        单例生命周期:容器创建时,就创建对象;容器摧毁时,就摧毁对象。
        多例生命周期:getBean方法被调用时,创建对象,对象销毁与spring无关,等待垃圾回收机制回收
    -->

set方法注入:

 <!--
           使用set注入时,bean类中需存在get set 方法
           set 方法注入  property和constructor-arg 使用时的区别
          (不用在意顺序)property注入时可以单个属性的注入,即想写几个属性就写几个(不能超过)
                        constructor-arg 注入时,需全部属性都注入,否则会报错
        -->
    <bean id="stu2" class="com.code.spring01.entity.Student">
        <property name="age" value="19"></property>
        <property name="name" value="张三"></property>
    </bean>
    <!-- <bean id="stu2" class="com.code.spring01.entity.Student">
         <constructor-arg name="name" value="张三"></constructor-arg>
     </bean>-->
    <!--
        set 注入的简写 方式
    -->
    <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<String> list;
    private Set<String> set;

    //map  properties
    private Map<String,String> map;
    private Properties properties;
    
    // 省略了set方法

bean注入:

<bean id="user" class="com.hopu.ioc.User">
        <property name="str">
            <array>
                <value>EE</value>
                <value>FF</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>AA</value>
                <value>BB</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>CC</value>
                <value>DD</value>
            </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">ii</prop>
                <prop key="JJ">jj</prop>
            </props>
        </property>
    </bean>

Bean的多模块注入:

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

   <!--
           在app.xml中导入app2.xml文件
    -->
    <import resource="app2.xml"/>

注解注入:

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

@Component("admin")  // 等同于bean id="admin" class="com.code.spring01.entity.Admin"></bean>
@Scope(scopeName = "singleton")  // 限制创建的为单例对象
//@Scope(scopeName = "prototype")  // 限制创建的为多例对象
//@Component("id") 取代 <bean id="" class="">
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;
    }    

 

个人学习,内容简略。

posted @ 2020-10-12 20:52  一生的风景  阅读(579)  评论(0编辑  收藏  举报