java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪

Posted Java_Pluto

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪相关的知识,希望对你有一定的参考价值。

前言

前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了。。。事后回家想了想这一块确实有点难度的就写篇文章把我自己知道的和网上整理的分享给大家,至少大家在被问到这一块的时候能答上来,不会因为这个被卡涨薪。话不多说,满满的干货都在下面了!

1.什么是Spring的依赖注入?

依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。

2. IOC的作用

降低程序间的耦合(依赖关系)

依赖关系的管理:

以后都交给spring来维护

在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护,就称之为依赖注入。

3.Spring依赖注入的几种方式

能注入的数据:有三类

基本类型和String。

其他bean类型(在配置文件中或者注解配置过的bean)。

复杂类型/集合类型。

注入的方式:有三种

使用构造函数提供。

使用set方法提供。

使用注解提供。

构造函数注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。具体代码如下:

<!--构造函数注入:
    使用的标签:constructor-arg
    标签出现的位置:bean标签的内部
    标签中的属性
        type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
        index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
        name:用于指定给构造函数中指定名称的参数赋值
        ================以上三个用于指定给构造函数中哪个参数赋值===================
        value:用于提供基本类型和String类型的数据
        ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

    优势:
        在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    弊端:
        改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value="泰斯特"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>

<!-- 配置一个日期对象 -->
<bean id="now" class="java.util.Date"></bean>

Set方式注入

顾名思义,就是在类中提供需要注入成员的 set 方法。具体代码如下:

<!-- set方法注入 --->   更常用的方式
    涉及的标签:property
    出现的位置:bean标签的内部
    标签的属性
        name:用于指定注入时所调用的set方法名称
        value:用于提供基本类型和String类型的数据
        ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
    优势:
        创建对象时没有明确的限制,可以直接使用默认构造函数
    弊端:
        如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
-->
<bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
    <property name="name" value="tom" ></property>
    <property name="age" value="23"></property>
    <property name="birthday" ref="now"></property>
</bean>

集合方式注入

顾名思义,就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。

我们这里介绍注入数组,List,Set,Map,Properties。

复杂类型的注入/集合类型的注入

用于给List结构集合注入的标签:

list,array,set

用于个Map结构集合注入的标签:

map,props

代码如下:
User类

public class User {
    private String name;
    private Integer age;
    private Date birth;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public User(){
        System.out.println("我被创建了...");
    }
    public void show(){
        System.out.println("user中的show方法调用了。。。");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                ", birth=" + birth +
                '}';
    }
}

Person类

public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '}';
    }
}

CollectionDemo类

 
public class CollectionDemo {
    private String[] arr;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProp;

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProp(Properties myProp) {
        this.myProp = myProp;
    }

    public String[] getArr() {
        return arr;
    }

    public List<String> getMyList() {
        return myList;
    }

    public Set<String> getMySet() {
        return mySet;
    }

    public Map<String, String> getMyMap() {
        return myMap;
    }

    public Properties getMyProp() {
        return myProp;
    }
}

配置文件:

<!-- 基于xml形式装配bean -->
<bean id="user" class="com.atguigu.java1.User"></bean>

<!--使用get方法创建bean-->
<bean id="user2" class="com.atguigu.java1.User">
    <property name="name" value="张"></property>
    <property name="age">
        <value>20</value>
    </property>
    <property name="birth" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

<!--集合和数组类型的依赖注入-->
<bean id="demo" class="com.atguigu.java1.CollectionDemo">
    <property name="arr">
        <array>
            <value>111</value>
            <value>222</value>
            <value>333</value>
        </array>
    </property>
    <property name="myList">
        <list>
            <value>111</value>
            <value>222</value>
            <value>333</value>
        </list>
    </property>
    <property name="mySet">
        <set>
            <value>111</value>
            <value>222</value>
            <value>333</value>
        </set>
    </property>
    <property name="myMap">
        <map>
            <entry key="aaa" value="aaa"></entry>
            <entry key="bbb" value="bbb"></entry>
            <entry key="ccc" value="ccc"></entry>
        </map>
    </property>
    <property name="myProp">
        <props>
            <prop key="aaa">aaa</prop>
            <prop key="bbb">bbb</prop>
            <prop key="ccc">ccc</prop>
        </props>
    </property>
</bean>

<!--使用默认构造器创建bean-->
<bean id="person" class="com.atguigu.java1.Person">
    <constructor-arg name="name" value="张三丰"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
</bean>

测试类:

/**
 * 测试基于xml形式的spring ioc获取对象
 */
@Test
public void test3(){
    ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
    User user= (User) ioc.getBean("user");//在此处打断点验证对象是什么时候被创建的。
    user.show();
}

/**
 * 采用默认构造器的形式创建bean对象
 */
@Test
public void test(){
    ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
    Person p= (Person) ioc.getBean("person");
    Person p2= (Person) ioc.getBean("person");
    System.out.println(p.toString());
}
/**
 * 使用get方法进行依赖注入
 */
@Test
public void test4(){
    ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
    User user= (User) ioc.getBean("user2");//在此处打断点验证对象是什么时候被创建的。
    System.out.println(user.toString());
}

/**
 * 集合和数组的依赖注入
 */
@Test
public void test5(){
    ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
    CollectionDemo demo= (CollectionDemo) ioc.getBean("demo");
    System.out.println(Arrays.toString(demo.getArr()));
    System.out.println(demo.getMyList());
    System.out.println(demo.getMySet());
    System.out.println(demo.getMyMap());
    System.out.println(demo.getMyProp());
}

4.使用spring的ioc实现账户的CRUD

4.1 基于xml形式

1.引用外部属性文件

2.SPEL表达式

Spring Expression Language,Spring表达式语言,简称SpEL。支持运行时查询并可以操作对象图。
和JSP页面上的EL表达式、Struts2中用到的OGNL表达式一样,SpEL根据JavaBean风格的getXxx()setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。

2.基本语法
SpEL使用#{}作为定界符,所有在大框号中的字符都将被认为是SpEL表达式。

3.使用字面量
    ●整数:<property name="count" value="#{5}"/>
    ●小数:<property name="frequency" value="#{89.7}"/>
    ●科学计数法:<property name="capacity" value="#{1e4}"/>
    ●String类型的字面量可以使用单引号或者双引号作为字符串的定界符号
        <property name=”name” value="#{'Chuck'}"/>
        <property name='name' value='#{"Chuck"}'/>
    ●Boolean:<property name="enabled" value="#{false}"/>

4.引用其他bean
    <bean id="emp04" class="com.atguigu.parent.bean.Employee">
        <property name="empId" value="1003"/>
        <property name="empName" value="jerry"/>
        <property name="age" value="21"/>
        <property name="detp" value="#{dept}"/>
    </bean>

5.引用其他bean的属性值作为自己某个属性的值
    <bean id="emp05" class="com.atguigu.parent.bean.Employee">
        <property name="empId" value="1003"/>
        <property name="empName" value="jerry"/>
        <property name="age" value="21"/>
        <property name="deptName" value="#{dept.deptName}"/>
    </bean>

6.调用非静态方法
    <!-- 创建一个对象,在SpEL表达式中调用这个对象的方法 -->
    <bean id="salaryGenerator" class="com.atguigu.spel.bean.SalaryGenerator"/>

    <bean id="employee" class="com.atguigu.spel.bean.Employee">
        <!-- 通过对象方法的返回值为属性赋值 -->
        <property name="salayOfYear" value="#{salaryGenerator.getSalaryOfYear(5000)}"/>
    </bean>

7.调用静态方法
    <bean id="employee" class="com.atguigu.spel.bean.Employee">
        <!-- 在SpEL表达式中调用类的静态方法 -->
        <property name="circle" value="#{T(java.lang.Math).PI*20}"/>
    </bean>

8.运算符
    ①算术运算符:+-*/%^
    ②字符串连接:+
    ③比较运算符:<>==<=>=、lt、gt、eq、le、ge
    ④逻辑运算符:and, or, not, |
    ⑤三目运算符:判断条件?判断结果为true时的取值:判断结果为false时的取值
    ⑥正则表达式:matches

代码如下:

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
  
    <bean id="accountDao" class="com.atguigu.dao.impl.AccountDaoImpl">
        <property name="runner" ref="runner"></property>
    </bean>
    <bean id="accountService" class="com.atguigu.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    <bean id="account" class="com.atguigu.domain.Account">以上是关于java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪的主要内容,如果未能解决你的问题,请参考以下文章

Java后端开发三年,你不得不了解的JVM

开发人员必学!想找工作的你还不看这份资料就晚了

卧槽!你还不了解JVM ?!

Spring功能介绍带你看看那些可能你还不知道的Spring技巧哦!

听说你还不知道CompletableFuture?

从设计模式+源码讲到Tomcat加载Spring,你还不懂?