Spring的DI关于依赖注入

24 篇文章 0 订阅

Spring的个人总结

懒加载,注解配置导入xml配置,bean的name的属性

上午主要在原有的xml配置文件中加入了懒加载

<bean id="lazyBean" class="com.lanou3g.spring.bean.LazyHeJinJie" lazy-init="true" init-method="init" />

懒加载,顾名思义,就是我们只有在getbean时,IOC容器才会给我们生成init方法和destroy方法,如果不在bean里面添加lazy-init=“true”,不管我们get不get这个bean,IOC都会生成init方法和destory方法,前提是bean里面声明init-method和destory-method实现类还要有这两个方法
bean的name方法
这里面name作用和id一样,只不过name可以有多个,而id只能有一个,通俗来讲id就像你的正名具有唯一性,而name就像你的别名,可以有多个,但是作用都是一样的,别人一喊反正都是你,你都会响应别人
这里面的id的值,如果只是xml配置不牵扯注解(注解就是在某个类添加@Component())id的值随意起,牵扯到注解,在某个类添加@Component(“kkk”)后就相当于在xml中配置了,不要在xml在配置这个类了

<bean id="student" name="stu,student1,sd1" class="com.lanou3g.spring.bean.Student">
    <constructor-arg name="nickName" value="三哥" />
    <constructor-arg name="sname" value="张三" />
    <constructor-arg name="fruit" ref="banana" />
</bean>

// 获取applicationContext.xml中配置的name属性为:stu,student1,sd1
Student stu = ctx.getBean(“sd1”, Student.class);
System.out.println(stu.getNickName());
注解配置导入xml配置
其实我们可以通过xml和注解中的任意一种去获得对象,在我们刚开始学的时xml中设置注解方式
<context:component-scan base-package=“com.lanou3g.spring” />
在xml中设置这个context 就可以扫描com.lanou3g.spring下所有的包,看哪些包下的类是带有注解的
后面学的是注解配置导入xml配置,简单来说,在某个类(App.java)加一个@Configuration
用@Configuration注解的类就相当于是一个xml的配置文件,然后我们在这个类中导入xml配置文件//@ImportResource(“applicationContext.xml”)
AnnotationApplicationContext用于初始化ioc容器(注解方式配置文件(用@Configuration注解的类))
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);
这种是获得App这个class类中的对象和导入这个类中的xml中的bean对应的对象

 ClassPathXmlApplicationContext用于初始化ioc容器(基于类路径下基于xml方式的配置)
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
   这种是获得xml中的bean的对象,以及xml中的<context:component-scan base-package="com.lanou3g.spring" />扫描com.lanou3g.spring下的注解

两种方式各有优势

注入匿名内部bean

先在xml中配置

<bean id="stu1" class="com.lanou3g.spring.bean.Student">
    <property name="fruit">
        <bean class="com.lanou3g.spring.simple.Apple" />
    </property>
</bean>
在方法中获得bean,进而调用

/**
* 通过标签注入一个匿名内部bean
*/
public void testInjectInnerBean(ApplicationContext ctx) {
Student stu = ctx.getBean(“stu1”, Student.class);
stu.getFruit().eatFruit();
}

注入集合型属性,注入null,空字符串类型属性值, 注入复合属性值

**<!-- 注入集合、Map类型参数 -->**
 在xml中配置list,map
<bean id="saiSai" class="com.lanou3g.spring.bean.JinSaiSai">
    <property name="hobbies">
        <list>
            <value>游泳</value>
            <value type="java.lang.Integer">0034</value>

//type是要输出的类型,如type为Integer,那么输出就是34,如果是String ,输出的是0034

**//注入null** **//注入空字符串** //在jinsaisai类型中有一个yinsaisai类型的属性,
        <bean class="com.lanou3g.spring.bean.YinSaiSai" />
    </property>
     //yinsaisai类型的属性中又包含了一个age属性,并且age属性值需要设置为28
    <property name="yinSaiSai.age" value="28" />
</bean>

/**
* 练习注入集合、Map类型…
* @param ctx
*/
在具体的方法中实现
public void testInjectListMap(ApplicationContext ctx) {
JinSaiSai saisai = ctx.getBean(JinSaiSai.class);
// 获取注入的list属性
List hobbies = saisai.getHobbies();
for(Object hobby : hobbies) {
System.out.println(“类型:” + hobby.getClass()+", 值:" + hobby);
}

    // 获取注入的map属性
    System.out.println(saisai.getGameTitles());

    // 获取普通属性nickName
    System.out.println("nickName: " + saisai.getNickName());

    // 获取关联对象中的属性值
    System.out.println("银赛赛中的age: " + saisai.getYinSaiSai().getAge());
}

注入外部properties文件的属性值

首先建一个文件放置配置文件的

jdbc.url=jdbc:mysql://localhost:3306/lanou?charsetEncoding=utf8
   jdbc.driver=com.mysql.jdbc.Driver
   jdbc.user=root
   jdbc.password=root
<!-- 方式一 -->
<!--<bean       class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:jdbc.properties" />
</bean>-->

<!-- 方式二 -->
<!-- 引入外部的properties文件结束 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

很显然方式二更方便点

 <!-- 将外部properties文件中的属性注入到bean中 -->
<bean id="jdbcConf" class="com.lanou3g.spring.bean.JDBCConf">
    <property name="url" value="${jdbc.url}" />
    <property name="driver" value="${jdbc.driver}" />
    <property name="userName" value="${jdbc.user}" />
    <property name="password" value="${jdbc.password}" />
</bean>


   然后在具体的方法中实现
/**
 * 练习注入外部properties配置文件
 * @param ctx
 */
public void testInjectProperties(ApplicationContext ctx) {
    JDBCConf jdbcConf = ctx.getBean(JDBCConf.class);
    System.out.println(jdbcConf.getUrl());
    System.out.println(jdbcConf.getDriver());
    System.out.println(jdbcConf.getUserName());
    System.out.println(jdbcConf.getPassword());
}

通过p命名空间注入属性

就是把xml的头几行

//xmlns:context="http://www.springframework.org/schema/context"
//xmlns:context="http://www.springframework.org/schema/context"
改成
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
<!-- 通过p命名空间来注入属性 -->
<!--<bean id="yunjie1" class="com.lanou3g.spring.bean.YunJie">
    <property name="sname" value="云姐" />
</bean>-->
<!-- 等效于上面的配置 -->
<bean id="yunjie1" class="com.lanou3g.spring.bean.YunJie" p:sname="云姐" />

 <!-- 通过c命名空间来注入构造参数 -->
<!--<bean id="yunjie2" class="com.lanou3g.spring.bean.YunJie">
    <constructor-arg name="sname" value="雲杰" />
</bean>-->
<!-- 等效于上面的配置 -->
<bean id="yunjie2" class="com.lanou3g.spring.bean.YunJie" c:sname="雲杰" />

/**
* 测试通过p和c命名空间注入属性和构造参数
*/

public void testInjectPAndC(ApplicationContext ctx) {
    YunJie yunJie1 = ctx.getBean("yunjie1", YunJie.class);
    System.out.println("yunjie1(通过p注入属性setter), sname: " + yunJie1.getSname());

    YunJie yunJie2 = ctx.getBean("yunjie2", YunJie.class);
    System.out.println("通过c注入构造参数, sname: " +yunJie2.getSname());
}

##构造方法注入

  • 有参和无参
<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <!-- 通过此标签注入构造方法中的参数 -->
      	<constructor-arg  name="age" value="18" />
      	<constructor-arg  type="java.lang.String" value="张三" />	
      	<constructor-arg ref="beanTwo"/>
    </bean>
<!--	<constructor-arg  name="age" value="18" />对应的是具体类的有参构造方法-->
    <bean id="beanTwo" class="x.y.ThingTwo"/>
</beans>
  • 通过c命名空间注入参数
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>

    <!-- 传统方式注入构造参数 -->
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg name="thingTwo" ref="beanTwo"/>
        <constructor-arg name="thingThree" ref="beanThree"/>
        <constructor-arg name="email" value="something@somewhere.com"/>
    </bean>

    <!-- c命名空间方式注入构造参数 -->
    <bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
        c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>

</beans>

##自动装配

  • ByName
package com.lanou3g.spring.bean;

import lombok.Getter;
import lombok.Setter;

/**
 * 自动装配属性
 */
@Getter
@Setter
public class AutoInjectByNameTeacher {
        private String tname;
        private Student student;
}

  • ByType
package com.lanou3g.spring.bean;

import lombok.Getter;
import lombok.Setter;

/**
 * 自动装配属性
 */
@Getter
@Setter
public class AutoInjectByTypeTeacher {

    public AutoInjectByTypeTeacher() {}

    public AutoInjectByTypeTeacher(LazyHeJinJie lazyHeJinJie) {
        System.out.println("构造参数传入: " + lazyHeJinJie);
        this.lazyStudent = lazyHeJinJie;
    }

    private String tname;
    private LazyHeJinJie lazyStudent;

    // 错误示范
    //    private Student student;
}

  • ByConstructor
package com.lanou3g.spring.bean;

import lombok.Getter;
import lombok.Setter;

/**
 * 自动装配属性
 */
@Getter
@Setter
public class AutoInjectByConstructorTeacher {

    public AutoInjectByConstructorTeacher() {}

    public AutoInjectByConstructorTeacher(LazyHeJinJie lazyHeJinJie) {
        System.out.println("构造参数传入: " + lazyHeJinJie);
        this.lazyStudent = lazyHeJinJie;
    }

    private String tname;
    private LazyHeJinJie lazyStudent;

    // 错误示范
    //    private Student student;
}

测试类实现

/**
     * 练习自动注入
     * @param ctx
     */
    public void testAutoInject(ApplicationContext ctx) {
        // 按照名称自动注入属性
      /*  AutoInjectByNameTeacher teacher = ctx.getBean("teacherByName" , AutoInjectByNameTeacher.class);
        System.out.println("教师名称: " + teacher.getTname());
        System.out.println("所教学生:" + teacher.getStudent().getSname());
*/
        // 按照类型自动注入属性(容器中符合此类型的bean只能有一个,否则报错)
       /* AutoInjectByTypeTeacher teacherByType = ctx.getBean("teacherByType" , AutoInjectByTypeTeacher.class);
        System.out.println("教师名称(类型): " + teacherByType.getTname());
        teacherByType.getLazyStudent().destroy();*/
        // 下面这行示范了按照类型自动注入,但符合类型不唯一的情况(会直接报错)
        // 解决方案就是换成按照名称自动注入
        //System.out.println("学生姓名:" + teacherByType.getStudent().getSname());


        // 构造器参数自动注入(按照类型)(容器中符合此类型的bean只能有一个,否则报错)
        AutoInjectByConstructorTeacher teacherByConstructor = ctx.getBean("teacherByConstructor" , AutoInjectByConstructorTeacher.class);
        System.out.println("教师名称(构造参数): " + teacherByConstructor.getTname());
        teacherByConstructor.getLazyStudent().destroy();

    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值