超级详细!!!Spring框架知识点完整版 上篇,SSM三部曲之一 知识点涵盖:Spring简介IOC控制反转DI依赖注入LombokSPEL配置文件低频知识点注解开发Spring常用注解

一、Spring简介

Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。

目前是JavaEE开发的灵魂框架。他可以简化JavaEE开发,可以非常方便整合其他框架,无侵入的进行功能增强。

Spring的核心就是 控制反转(IoC)和面向切面(AOP) 。

二、IOC控制反转

这里推荐观看哔哩哔哩up主“三更草堂”Spring5讲解中 第二节SpringIOC引入的内容,23分钟通俗易懂。

链接:https://www.bilibili.com/video/BV1G54y1V7VG?p=17&spm_id_from=pageDriver

2.1 概念

控制反转,之前对象的控制权在类手上,现在反转后到了Spring手上。

  Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

  ●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

  ●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

以下IOC详解内容原作者:https://www.cnblogs.com/wmyskxz/p/8824597.html

image.png

2.2 入门案例

①导入依赖

导入SpringIOC相关依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>

②编写配置文件

在resources目录下创建applicationContext.xml文件,文件名可以任意取。但是建议叫applicationContext。

image.png

内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        classs:配置类的全类名
        id:配置一个唯一标识
    -->
    <bean class="com.sangeng.dao.impl.StudentDaoImpl" id="studentDao"  >
    </bean>
</beans>

③创建容器从容器中获取对象并测试

public static void main(String[] args) {
//        1.获取StudentDaoImpl对象
        //创建Spring容器,指定要读取的配置文件路径
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //从容器中获取对象
        StudentDao studentDao = (StudentDao) app.getBean("studentDao");
        //调用对象的方法进行测试
        System.out.println(studentDao.getStudentById(1));
    }

2.3 Bean的常用属性配置

2.3.1 id

bean的唯一标识,同一个Spring容器中不允许重复

2.3.2 class

全类名,用于反射创建对象

2.3.3 scope

spring的Bean默认的是单例的,Bean的作用域可以通过Bean标签的scope属性进行设置,Bean的作用域包括:
默认情况下scope="singleton",那么该Bean是单例,任何人获取该Bean实例的都为同一个实例;
scope="prototype",任何一个实例都是新的实例;
scope="request",在WEB应用程序中,每一个实例的作用域都为request范围;

scope="session",在WEB应用程序中,每一个实例的作用域都为session范围;

注意:在默认情况下,Bean实例在被Spring容器初始化的时候,就会被实例化,默认调用无参数的构造方法。在其它情况下,Bean将会在获取实例的时候才会被实例化。

单例模式分为饿汉模式和懒汉模式:

饿汉模式spring singleton的缺省是饿汉模式:启动容器时(即实例化容器时),为所有spring配置文件中定义的bean都生成一个实例
懒汉模式在第一个请求时才生成一个实例,以后的请求都调用这个实例
spring singleton设置为懒汉模式:<beans default-lazy-init="true">

prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。

Spring中说的单例是相对于容器的,既在ApplicationContext中是单例的。而平常说的单例是相对于JVM的。另一个JVM可以有多个Spring容器,而且Spring中的单例也只是按bean的id来区分的。

懒汉式和饿汉式的安全和性能区别:

(1) 线程安全:饿汉式在线程还没出现之前就已经实例化了,所以饿汉式一定是线程安全的。懒汉式加载是在使用时才会去new 实例的,那么你去new的时候是一个动态的过程,是放到方法中实现的,比如:   

public static synchronized Singleton getInstance(){
         if(instance == null){
     //什么时候用就什么时候new
             instance = new Singleton();
         }

如果这个时候有多个线程访问这个实例,这个时候实例还不存在,还在new,就会进入到方法中,有多少线程就会new出多少个实例。一个方法只能return一个实例,那最终return出哪个呢?是不是会覆盖很多new的实例?这种情况当然也可以解决,那就是加同步锁,避免这种情况发生 。

(2)执行效率:饿汉式没有加任何的锁,因此执行效率比较高。懒汉式一般使用都会加同步锁,效率比饿汉式差。
(3)内存使用:饿汉式在一开始类加载的时候就实例化,无论使用与否,都会实例化,所以会占据空间,浪费内存。懒汉式什么时候用就什么时候实例化,不浪费内存。

单例模式三要素

(1)、getInstance方法双重检查创建实例。

image.png

(2)、含有一个该类的静态变量来保存这个唯一的实例。

(3)、构造器私有化:把构造函数置空,同时加上了private保证外界无法访问,用户即使new了一个也无法再次创建单例对象,要用这个对象只能通过暴露给外界的getInstance方法获取

三、DI依赖注入

依赖注入可以理解成IoC的一种应用场景,反转的是对象间依赖关系维护权。

DI—Dependency Injection,即“依赖注入”组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

  理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

  ●谁依赖于谁:当然是应用程序依赖于IoC容器

  ●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源

  ●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象

  ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

  IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

3.1 set方法注入

在要注入属性的bean标签中进行配置。前提是该类有提供属性对应的set方法。

package com.sangeng.domain;
public class Student {
    private String name;
    private int id;
    private int age;
    private Dog dog;
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
    public Student() {
    }
    public Student(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

============================================================
    <bean class="com.sangeng.domain.Dog" id="dog">
        <property name="name" value="小白"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean class="com.sangeng.domain.Student" id="student" >
        <!--
            name属性用来指定要设置哪个属性
            value属性用来设置要设置的值
            ref属性用来给引用类型的属性设置值,可以写上Spring容器中bean的id
        -->
        <property name="name" value="东南枝"></property>
        <property name="age" value="20"></property>
        <property name="id" value="1"></property>
        <property name="dog" ref="dog"></property>
    </bean>

3.2 有参构造注入

在要注入属性的bean标签中进行配置。前提是该类有提供对应的有参构造。

public class Student {
    private String name;
    private int id;
    private int age;
    private Dog dog;
    public Student(String name, int id, int age, Dog dog) {
        this.name = name;
        this.id = id;
        this.age = age;
        this.dog = dog;
    }
    //.....省略其他
}
==================================================================
    <!--使用有参构造进行注入-->
    <bean class="com.sangeng.domain.Student" id="student2" >
        <constructor-arg name="name" value="自挂东南枝"></constructor-arg>
        <constructor-arg name="age" value="20"></constructor-arg>
        <constructor-arg name="id" value="30"></constructor-arg>
        <constructor-arg name="dog" ref="dog"></constructor-arg>
    </bean>

3.3 复杂类型属性注入

实体类如下:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int age;
    private String name;
    private Phone phone;
    private List<String> list;
    private List<Phone> phones;
    private Set<String> set;
    private Map<String, Phone> map;
    private int[] arr;
    private Properties properties;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
    private double price;
    private String name;
    private String password;
    private String path;
}

配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean class="com.sangeng.domain.Phone" id="phone">
        <property name="price" value="3999"></property>
        <property name="name" value="黑米"></property>
        <property name="password" value="123"></property>
        <property name="path" value="qqqq"></property>
    </bean>
    
    <bean class="com.sangeng.domain.User" id="user">
        <property name="age" value="10"></property>
        <property name="name" value="大队长"></property>
        <property name="phone" ref="phone"></property>
        <property name="list">
            <list>
                <value>三更</value>
                <value>西施</value>
            </list>
        </property>
        <property name="phones">
            <list>
                <ref bean="phone"></ref>
            </list>
        </property>
        <property name="set">
            <set>
                <value>setEle1</value>
                <value>setEle2</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="k1" value-ref="phone"></entry>
                <entry key="k2" value-ref="phone"></entry>
            </map>
        </property>
        <property name="arr">
            <array>
                <value>10</value>
                <value>11</value>
            </array>
        </property>
        <property name="properties">
            <props>
                <prop key="k1">v1</prop>
                <prop key="k2">v2</prop>
            </props>
        </property>
    </bean>
</beans>

四、Lombok

①导入依赖

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

②增加注解

@Data //根据属性生成set,get方法
@NoArgsConstructor //生成空参构造
@AllArgsConstructor //生成全参构造
public class Phone {
    private double price;
    private String name;
    private String password;
    private String path;
}

五、SPEL

我们可以再配置文件中使用SPEL表达式。写法如下:

<property name="age" value="#{20}"/>
        <property name="car" value="#{car}"/>

注意:SPEL需要写到value属性中,不能写到ref属性。

六、配置文件

6.1 读取properties文件

我们可以让Spring读取properties文件中的key/value,然后使用其中的值。

①设置读取properties

在Spring配置文件中加入如下标签:指定要读取的文件的路径。

<context:property-placeholder location="classpath:filename.properties">

其中的classpath表示类加载路径下。

我们也会用到如下写法:classpath:*.properties 其中的 * 表示文件名任意。

注意:context命名空间的引入是否正确

②使用配置文件中的值

在我们需要使用的时候可以使用${key}来表示具体的值。注意要再value属性中使用才可以。例如:

<property name="propertyName" value="${key}"/>

6.2 引入Spring配置文件

我们可以在主的配置文件中通过import标签的resource属性,引入其他的xml配置文件

<import resource="classpath:applicationContext-book.xml"/>

七、低频知识点

7.1 bean的配置

7.1.1 name属性

我们可以用name属性来给bean取名。例如:

<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource" name="dataSource2,dataSource3">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    获取的时候就可以使用这个名字来获取了
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        DruidDataSource dataSource = (DruidDataSource) app.getBean("dataSource3");
        System.out.println(dataSource);
    }

7.1.2 lazy-init

可以控制bean的创建时间,如果设置为true就是在第一次获取该对象的时候才去创建。 懒汉式-饿汉式搞好

<bean class="com.alibaba.druid.pool.DruidDataSource" lazy-init="true"  id="dataSource" name="dataSource2,dataSource3">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

7.1.3 init-method

可以用来设置初始化方法,设置完后容器创建完对象就会自动帮我们调用对应的方法。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String name;
    private int id;
    private int age;
    //初始化方法
    public void init(){
        System.out.println("对学生对象进行初始化操作");
    }
}


<bean class="com.sangeng.domain.Student" id="student" init-method="init"></bean>

注意:配置的初始化方法只能是空参的。

7.1.4 destroy-method

可以用来设置销毁之前调用的方法,设置完后容器销毁对象前就会自动帮我们调用对应的方法。

<bean class="com.sangeng.domain.Student" id="student"  destroy-method="close"></bean>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String name;
    private int id;
    private int age;
    public void init(){
        System.out.println("对学生对象进行初始化操作");
    }
    public void close(){
        System.out.println("对象销毁之前调用,用于释放资源");
    }
}

注意:配置的方法只能是空参的。

7.1.5 factory-bean&factory-method

当我们需要让Spring容器使用工厂类来创建对象放入Spring容器的时候可以使用factory-bean和factory-method属性。

7.1.5.1 配置实例工厂创建对象

配置文件中进行配置

<!--创建实例工厂-->
    <bean class="com.sangeng.factory.CarFactory" id="carFactory"></bean>
    <!--使用实例工厂创建Car放入容器-->
    <!--factory-bean 用来指定使用哪个工厂对象-->
    <!--factory-method 用来指定使用哪个工厂方法-->
    <bean factory-bean="carFactory" factory-method="getCar" id="car"></bean>
创建容器获取对象测试
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取car对象
        Car c = (Car) app.getBean("car");
        System.out.println(c);

7.1.5.2 配置静态工厂创建对象

配置文件中进行配置

<!--使用静态工厂创建Car放入容器-->
    <bean class="com.sangeng.factory.CarStaticFactory" factory-method="getCar" id="car2"></bean>

创建容器获取对象测试

ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取car对象
        Car c = (Car) app.getBean("car2");
        System.out.println(c);

八、注解开发

为了简化配置,Spring支持使用注解代替xml配置。

九、Spring常用注解

2.0 注解开发准备工作

如果要使用注解开发必须要开启组件扫描,这样加了注解的类才会被识别出来。Spring才能去解析其中的注解。

<!--启动组件扫描,指定对应扫描的包路径,该包及其子包下所有的类都会被扫描,加载包含指定注解的类-->
<context:component-scan base-package="com.sangeng"/>

2.1 IOC相关注解

2.1.1 @Component,@Controller,@Service ,@Repository

上述4个注解都是加到类上的。

他们都可以起到类似bean标签的作用。可以把加了该注解类的对象放入Spring容器中。

实际再使用时选择任意一个都可以。但是后3个注解是语义化注解。

如果是Service类要求使用@Service。

如果是Dao类要求使用@Repository

如果是Controllerl类(SpringMVC中会学习到)要求使用@Controller

如果是其他类可以使用@Component

例如:

配置文件如下:

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--启动组件扫描,指定对应扫描的包路径,该包及其子包下所有的类都会被扫描,加载包含指定注解的类-->
    <context:component-scan base-package="com.sangeng"></context:component-scan>
</beans>

类如下:

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void show() {
        System.out.println("查询数据库,展示查询到的数据");
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component("phone")
public class Phone {
    private double price;
    private String name;
    private String password;
    private String path;
}
@Service("userService")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    private int num;
    private String str;
    public void show() {
        userDao.show();
    }
}

测试类如下:

public class Demo {
    public static void main(String[] args) {
        //创建容器
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取对象
        UserDao userDao = (UserDao) app.getBean("userDao");
        Phone phone = (Phone) app.getBean("phone");
        UserService userService = (UserService) app.getBean("userService");
        System.out.println(phone);
        System.out.println(userService);
        System.out.println(userDao);
    }
}

2.2 DI相关注解

如果一个bean已经放入Spring容器中了。那么我们可以使用下列注解实现属性注入,让Spring容器帮我们完成属性的赋值。

2.2.1 @Value

主要用于String,Integer等可以直接赋值的属性注入。不依赖setter方法,支持SpEL表达式。

例如:

@Service("userService")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    @Value("199")
    private int num;
    @Value("三更草堂")
    private String str;
    @Value("#{19+3}")
    private Integer age;
    public void show() {
        userDao.show();
    }
}

2.2.2 @AutoWired

Spring会给加了该注解的属性自动注入数据类型相同的对象。

例如:

@Service("userService")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Value("199")
    private int num;
    @Value("三更草堂")
    private String str;
    @Value("#{19+3}")
    private Integer age;
    public void show() {
        userDao.show();
    }
}

required属性代表这个属性是否是必须的,默认值为true。如果是true的话Spring容器中如果找不到相同类型的对象完成属性注入就会出现异常。

扩展:

@Resource和@Autowired

@Resource和@Autowired都可以用来装配bean,都可以用于字段或setter方法。

@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false。

@Resource默认按名称装配,当找不到与名称匹配的bean时才按照类型进行装配。名称可以通过name属性指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,当注解写在setter方法上时,默认取属性名进行装配。

2.2.3 @Qualifier

如果相同类型的bean在容器中有多个时,单独使用@AutoWired就不能满足要求,这时候可以再加上@Qualifier来指定bean的名字从容器中获取bean注入。

例如:

    @Autowired
    @Qualifier("userDao2")
    private UserDao userDao;

注意:该直接不能单独使用。单独使用没有作用

2.3 xml配置文件相关注解

@Configuration

标注在类上,表示当前类是一个配置类。我们可以用注解类来完全替换掉xml配置文件。

注意:如果使用配置类替换了xml配置,spring容器要使用:AnnotationConfigApplicationContext

例如:

@Configuration
public class ApplicationConfig {
}

@ComponentScan

可以用来代替context:component-scan标签来配置组件扫描。

basePackages属性来指定要扫描的包。

注意要加在配置类上。

例如:

@Configuration
@ComponentScan(basePackages = "com.sangeng")//指定要扫描的包
public class ApplicationConfig {
}

@Bean

可以用来代替bean标签,主要用于第三方类的注入。

使用:定义一个方法,在方法中创建对应的对象并且作为返回值返回。然后在方法上加上@Bean注解,注解的value属性来设置bean的名称。

例如:

@Configuration
@ComponentScan(basePackages = "com.sangeng")
public class ApplicationConfig {
    @Bean("dataSource")
    public DruidDataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUsername("root");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_db");
        druidDataSource.setPassword("root");
        return druidDataSource;
    }
}

注意事项:如果同一种类型的对象在容器中只有一个,我们可以不设置bean的名称。

具体写法如下:

@Configuration
@ComponentScan(basePackages = "com.sangeng")
public class ApplicationConfig {
    @Bean
    public DruidDataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUsername("root");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_db");
        druidDataSource.setPassword("root");
        return druidDataSource;
    }
}

获取方式如下:

public static void main(String[] args) {
        //创建注解容器
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ApplicationConfig.class);
    //根据对应类的字节码对象获取
        DataSource bean = app.getBean(DataSource.class);
        System.out.println(userService);
    }

@PropertySource

可以用来代替context:property-placeholder,让Spring读取指定的properties文件。然后可以使用@Value来获取读取到的值。

使用:在配置类上加@PropertySource注解,注解的value属性来设置properties文件的路径。

然后在配置类中定义成员变量。在成员变量上使用@Value注解来获取读到的值并给对应的成员变量赋值。

例如:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_db
jdbc.username=root
jdbc.password=root

读取文件并且获取值

@Configuration
@ComponentScan(basePackages = "com.sangeng")
@PropertySource("jdbc.properties")
public class ApplicationConfig {
    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Bean
    public DruidDataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUsername(username);
        druidDataSource.setUrl(url);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }
}

注意事项:使用@Value获取读到的properties文件中的值时使用的是${key},而不是#{key}。

3.如何选择

①SSM

自己项目中的类的IOC和DI都使用注解,对第三方jar包中的类,配置组件扫描时使用xml进行配置。

②SpringBoot

纯注解开发

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rabbit Coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值