[SSM]Spring对IoC的实现

目录

四、Spring对IoC的实现

4.1IoC控制反转

4.2依赖注入

4.2.1set注入

4.2.2构造注入

4.3set注入专题

4.3.1注入外部Bean

4.3.2注入内部Bean

4.3.3注入简单类型

4.3.4级联属性赋值

4.3.5注入数组

4.3.6注入List、Set、Map集合

4.3.7注入Properties

4.3.8注入null和空字符串

4.3.9注入的值中含有特殊符号

4.4p命名空间注入

4.5c命名空间注入

4.6util命名空间

4.7基于XML的自动装配

4.7.1根据名称自动装配

4.7.2根据类型自动装配

4.8Spring引入外部属性配置文件


四、Spring对IoC的实现

4.1IoC控制反转

  • 控制反转是一种思想。

  • 控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则、DIP原则。

  • 控制反转,反转的是什么?

    • 将对象的创建权交出去,交给第三方容器负责。

    • 将对象和对象之间的关系维护权交出去,交给第三方容器负责。

  • 控制反转这种思想如何实现?

    • DI(Dependency Injection):依赖注入

4.2依赖注入

  • 依赖注入实现了控制反转的思想。

  • Spring通过依赖注入的方式来完成Bean的管理。

  • Bean的管理说的是:Bean对象的创建,以及Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)。

  • 依赖注入:

    • 依赖指的是对象和对象之间的关联关系。

    • 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。

  • 依赖注入常见的实现方式包括两种:

    • 第一种:set注入。

    • 第二种:构造注入。

4.2.1set注入
  • set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。这种机制要求属性必须对外提供set方法。

UserDao

package com.hhb.dao;
​
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
​
public class UserDao {
    private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
    public void insert() {
        //使用log4j2日志框架
        logger.info("数据库正在保存用户信息");
    }
}

UserService

package com.hhb.service;
​
import com.hhb.dao.UserDao;
import com.hhb.dao.VipDao;
​
public class UserService {
    private UserDao userDao;
    //set注入的话,必须提供一个set方法
    //Spring容器会调用这个set方法来给userDao属性赋值。
    //set方法必须以set单词开头
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void saveUser() {
        //保存用户信息到数据库
        userDao.insert();
        vipDao.insert();
    }
}

spring.xml

<?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">
​
    <!--配置dao-->
    <bean id="userDaoBean" class="com.hhb.dao.UserDao"/>
​
    <!--配置service-->
    <bean id="userServiceBean" class="com.hhb.service.UserService">
        <!--想让spring调用对应的set方法,需要配置property标签-->
        <!--name属性是set方法的方法名,去掉set,然后把剩下的单词首字母变小写-->
        <!--ref翻译为引用,全拼为references。ref后面要指定的是要注入bean的id-->
        <property name="userDao" ref="userDaoBean"/>
    </bean>
</beans>

测试

@Test
    public void testSetDI(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        UserService userServiceBean = applicationContext.getBean("userServiceBean", UserService.class);
        userServiceBean.saveUser();
    }
  • 实现原理:

    • 通过property标签获取到属性名:userDao

    • 通过属性名推断出set方法名:setUserDao

    • 通过反射机制调用setUserDao()方法给属性赋值

    • property标签的name是属性名

    • property标签的ref是要注入的bean对象的id。(通过ref属性来完成bean的装配,这是bean最简单的一种装配方式。装配指的是:创建系统组件之间关联的动作)

  • set注入的核心实现原理:通过反射机制调用set方法来给属性赋值,让两个对象之间产生关系。

4.2.2构造注入
  • 核心原理:通过调用构造方法来给属性赋值。

UserDao

package com.hhb.dao;
​
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
​
public class UserDao {
    private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
    public void insert() {
        //使用log4j2日志框架
        logger.info("数据库正在保存用户信息");
    }
}

VipDao

package com.hhb.dao;
​
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
​
public class VipDao {
    private static final Logger logger=LoggerFactory.getLogger(VipDao.class);
​
    public void insert(){
        logger.info("正在保存VIP信息");
    }
}

CustomerService

package com.hhb.service;
​
import com.hhb.dao.UserDao;
import com.hhb.dao.VipDao;
​
public class CustomerService {
    private UserDao userDao;
    private VipDao vipDao;
​
    public CustomerService(UserDao userDao, VipDao vipDao) {
        this.userDao = userDao;
        this.vipDao = vipDao;
    }
​
    public void save() {
        userDao.insert();
        vipDao.insert();
    }
}
 

beans.xml

<?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 id="userDaoBean" class="com.hhb.dao.UserDao"/>
    <bean id="vipDaoBean" class="com.hhb.dao.VipDao"/>
​
    <bean id="csBean3" class="com.hhb.service.CustomerService">
        <!--不指定下标,也不指定参数名,让spring自己做类型匹配-->
        <!--这种方式实际上是根据类型进行注入的,spring会自动根据类型来判断把ref注入到哪个参数-->
        <constructor-arg ref="userDaoBean"/>
        <constructor-arg ref="vipDaoBean"/>
    </bean>
​
    <bean id="csBean2" class="com.hhb.service.CustomerService">
        <!--根据构造方法参数的名字进行注入-->
        <constructor-arg name="vipDao" ref="vipDaoBean"/>
        <constructor-arg name="userDao" ref="userDaoBean"/>
    </bean>
​
    <bean id="csBean" class="com.hhb.service.CustomerService">
        <!--构造注入-->
        <!--
            index属性指定参数下标,第一个参数是0,第二个参数是2...
            ref属性用来指定注入的bean的id
        -->
        <constructor-arg index="0" ref="userDaoBean"/>
        <constructor-arg index="1" ref="vipDaoBean"/>
    </bean>
</beans>

测试

@Test
    public void testConstructDI() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        CustomerService csBean = applicationContext.getBean("csBean", CustomerService.class);
        csBean.save();
​
        CustomerService csBean2 = applicationContext.getBean("csBean2", CustomerService.class);
        csBean2.save();
​
        CustomerService csBean3 = applicationContext.getBean("csBean3", CustomerService.class);
        csBean3.save();
    }
  • 通过测试得知,通过构造方法注入的时候:

    • 可以通过下标

    • 可以通过参数名

    • 也可以不指定下标和参数名,可以类型自动推断

4.3set注入专题

4.3.1注入外部Bean

set-di.xml

<bean id="orderDaoBean" class="com.hhb.dao.OrderDao"/>
​
    <bean id="orderServiceBean" class="com.hhb.service.OrderService">
        <property name="orderDao" ref="orderDaoBean"/>
    </bean>
  • 外部Bean的特点:bean定义到外面,在property标签中使用ref属性进行注入,通常这种方式是常用的。

4.3.2注入内部Bean

set-di.xml

 <bean id="orderServiceBean2" class="com.hhb.service.OrderService">
     <property name="orderDao">
         <bean class="com.hhb.dao.OrderDao"/>
     </property>
 </bean>
  • 这种方式作为了解。

4.3.3注入简单类型

第一步:定义User类,提供setter方法

package com.hhb.bean;
​
public class User {
    private String username; // String是简单类型
    private String password;
    private int age; // int是简单类型
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}

第二步:set-di.xml

<bean id="userBean" class="com.hhb.bean.User">
    <!--重点:如果给简单类型赋值,需要使用value-->
    <property name="username" value="张三"/>
    <property name="password" value="123"/>
    <property name="age" value="19"/>
</bean>

第三步:测试

    @Test
    public void testSimpleTypeSet() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");
        User user = applicationContext.getBean("userBean", User.class);
        System.out.println(user);
    }
  • 简单类型包括:

    • 基本数据类型

    • 基本数据类型对应的包装类

    • String或其他的CharSequence子类

    • Number子类

    • Date子类

    • Enum子类

    • URL

    • URI

    • Temporal子类

    • Locale

    • Class

    • 以上简单值类型对应的数组类型

SimpleValueType

package com.powernode.spring6.beans;
import java.net.URI;
import java.net.URL;
import java.time.LocalDate;
import java.util.Date;
import java.util.Locale;
public class A {
 private byte b;
 private short s;
 private int i;
 private long l;
 private float f;
 private double d;
 private boolean flag;
 private char c;
 private Byte b1;
 private Short s1;
 private Integer i1;
 private Long l1;
 private Float f1;
 private Double d1;
 private Boolean flag1;
 private Character c1;
 private String str;
 private Date date;
 private Season season;
 private URI uri;
 private URL url;
 private LocalDate localDate;
 private Locale locale;
 private Class clazz;
 
 // ⽣成setter⽅法
 // ⽣成toString⽅法
}
enum Season {
 SPRING, SUMMER, AUTUMN, WINTER
}
  • 如果把Date当做简单类型的话,日期字符串格式不能随便写。必须按照这种格式写:Wed Oct 19 16:28:13 CST 2022

经典案例:给数据源的属性注入值

MyDataSource

package com.hhb.jdbc;
​
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
​
public class MyDataSource implements DataSource {
    private String driver;
    private String url;
    private String username;
    private String password;
​
    public void setDriver(String driver) {
        this.driver = driver;
    }
​
    public void setUrl(String url) {
        this.url = url;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    @Override
    public String toString() {
        return "MyDataSource{" +
                "driver='" + driver + '\'' +
                ", url='" + url + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
​
    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }
​
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }
​
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }
​
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
​
    }
​
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
​
    }
​
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }
​
    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
​
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }
​
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}

set-di.xml

<bean id="mds" class="com.hhb.jdbc.MyDataSource">
        <property name="username" value="root"/>
        <property name="password" value="123123"/>
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring"/>
    </bean>
4.3.4级联属性赋值

Student

package com.hhb.bean;
​
public class Student {
    private String name;
​
    //学生属于哪个班级
    private Clazz clazz;
​
    public void setName(String name) {
        this.name = name;
    }
​
    public void setClazz(Clazz clazz) {
        this.clazz = clazz;
    }
​
    //使用级联属性赋值,需要get方法
    public Clazz getClazz() {
        return clazz;
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", clazz=" + clazz +
                '}';
    }
}

Clazz

package com.hhb.bean;
​
public class Clazz {
    private String name;
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public String toString() {
        return "Clazz{" +
                "name='" + name + '\'' +
                '}';
    }
}

cascade.xml

<?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">
​
    <!--使用级联属性赋值需要注意:
        配置的顺序不能颠倒,必须以如下顺序
        clazz属性必须提供getter方法
    -->
    <bean id="studentBean" class="com.hhb.bean.Student">
        <!--简单类型使用value-->
        <property name="name" value="张三"/>
        <!--这不是简单类型,使用ref-->
        <property name="clazz" ref="clazzBean"/>
        <!--级联属性赋值-->
        <property name="clazz.name" value="大二"/>
    </bean>
​
    <bean id="clazzBean" class="com.hhb.bean.Clazz"/>
</beans>
4.3.5注入数组

Array1

package com.hhb.bean;
​
import java.util.Arrays;
​
public class Array1 {
    private String[] hobbies;
​
    private Array2[] array2;
​
    public void setArray2(Array2[] array2) {
        this.array2 = array2;
    }
​
    public void setHobbies(String[] hobbies) {
        this.hobbies = hobbies;
    }
​
    @Override
    public String toString() {
        return "Array1{" +
                "hobbies=" + Arrays.toString(hobbies) +
                ", array2=" + Arrays.toString(array2) +
                '}';
    }
}

Array2

package com.hhb.bean;
​
public class Array2 {
    private String name;
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public String toString() {
        return "Array2{" +
                "name='" + name + '\'' +
                '}';
    }
}

spring-array.xml

<?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 id="w1" class="com.hhb.bean.Array2">
        <property name="name" value="小红"/>
    </bean>
    <bean id="w2" class="com.hhb.bean.Array2">
        <property name="name" value="小花"/>
    </bean>
    <bean id="w3" class="com.hhb.bean.Array2">
        <property name="name" value="小丽"/>
    </bean>
        
    <bean id="array1" class="com.hhb.bean.Array1">
        <!--简单类型-->
        <property name="hobbies">
            <array>
                <value>抽烟</value>
                <value>喝酒</value>
                <value>烫头</value>
            </array>
        </property>
        <!--非简单类型-->
        <property name="array2">
            <array>
                <ref bean="w1"/>
                <ref bean="w2"/>
                <ref bean="w3"/>
            </array>
        </property>
    </bean>
</beans>
4.3.6注入List、Set、Map集合

Person

package com.hhb.bean;
​
import java.util.List;
import java.util.Map;
import java.util.Set;
​
public class Person {
    private List<String> names;
    private Set<String> phones;
    private Map<Integer, String> adrrs;
​
    public void setNames(List<String> names) {
        this.names = names;
    }
​
    public void setPhones(Set<String> phones) {
        this.phones = phones;
    }
​
    public void setAdrrs(Map<Integer, String> adrrs) {
        this.adrrs = adrrs;
    }
​
    @Override
    public String toString() {
        return "Person{" +
                "names=" + names +
                ", phones=" + phones +
                ", adrrs=" + adrrs +
                '}';
    }
}
​

spring-collection.xml

<?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 id="personBean" class="com.hhb.bean.Person">
        <property name="names">
            <!--list集合有序可重复-->
            <list>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
                <value>张三</value>
            </list>
        </property>
        <property name="phones">
            <!--set集合无须不可重复-->
            <set>
                <value>110</value>
                <value>120</value>
                <value>110</value>
            </set>
        </property>
        <property name="adrrs">
            <!--注入Map集合-->
            <map>
                <!--如果key和value不是简单类型,使用:<entry key-ref="" value-ref=""/>-->
                <!--简单类型-->
                <entry key="1" value="北京"/>
                <entry key="2" value="南京"/>
            </map>
        </property>
    </bean>
</beans>
4.3.7注入Properties

Property

package com.hhb.bean;
​
import java.util.Properties;
​
public class Property {
    private Properties properties;
​
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
​
    @Override
    public String toString() {
        return "Property{" +
                "properties=" + properties +
                '}';
    }
}
  • Properties本质上也是一个Map集合。

  • Properties的父类Hashtable实现了Map接口。

  • Properties的key和value只能是String类型。

spring-properties.xml

<?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 id="propertiesBean" class="com.hhb.bean.Property">
        <property name="properties">
            <props>
                <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
                <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
</beans>
4.3.8注入null和空字符串
<bean id="catBean" class="com.hhb.bean.Cat">
    <!--不给属性注入,默认的属性值就是null-->
    <!--<property name="name" value="tom"/>-->
    <!--这种方式是手动注入null-->
    <property name="name">
        <null/>
    </property>
    <!--注入空字符串第一种方式-->
    <!--property name="name" value=""/>-->
    <!--注入空字符串第二种方式-->
    <!--<property name="name">
        <value/>
    </property>-->
    <property name="age" value="3"/>
</bean>
4.3.9注入的值中含有特殊符号
  • XML中有5个特殊字符,分别是:<、>、'、"、&

  • 以上5个特殊符号在XML中会被特殊对待,会被当做XML语法的一部分进行解析,如果这些特殊符号直接出现在注入的字符串当中,会报错。

    特殊字符转义字符
    >>
    <<
    ''
    ""
    &&
<bean id="mathBean" class="com.hhb.bean.Math">
    <!--使用实体符号代替特殊符号-->
    <!--<property name="result" value="2&lt;3"/>-->
    <property name="result">
        <!--使用<![CDATA[]],只能在value标签中使用-->
        <value><![CDATA[2<3]]></value>
    </property>
</bean>

4.4p命名空间注入

  • 目的:简化配置

Dog

package com.hhb.bean;
​
import java.util.Date;
​
public class Dog {
    // 简单类型
    private String name;
    private int age;
    // 非简单类型
    private Date birth;
​
    // p命名空间注入底层还是set注入,只不过p命名空间注入可以让spring配置变的更加简单。
    public void setName(String name) {
        this.name = name;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public void setBirth(Date birth) {
        this.birth = birth;
    }
​
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birth=" + birth +
                '}';
    }
}

spring-p.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--在spring配置文件头部添加p命名空间。xmlns:p="http://www.springframework.org/schema/p"-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <!--使用 p:属性名="属性值"-->
    <bean id="dogBean" class="com.hhb.bean.Dog" p:name="tom" p:age="3" p:birth-ref="birthBean"/>
​
    <bean id="birthBean" class="java.util.Date"/>
</beans>

4.5c命名空间注入

  • c命名空间是简化构造方法注入的。

People

package com.hhb.bean;
​
public class People {
    private String name;
    private String age;
    private Boolean flag;
​
    //c命名空间是简化构造注入的
    //c命名空间注入办法是基于构造方法的
    public People(String name, String age, Boolean flag) {
        this.name = name;
        this.age = age;
        this.flag = flag;
    }
​
    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", flag=" + flag +
                '}';
    }
}

spring-c.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--在spring的配置文件头部添加:xmlns:c="http://www.springframework.org/schema/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 http://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <!--下标方式-->
    <!--<bean id="peopleBean" class="com.hhb.bean.People" c:_0="张三" c:_1="25" c:_2="true"/>-->
    <!--参数名方式-->
    <bean id="peopleBean" class="com.hhb.bean.People" c:name="张三" c:age="25" c:flag="true"/>
</beans>

4.6util命名空间

  • 使用util命名空间可以让配置复用。

MyDataSource1

package com.hhb.jdbc;
​
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Properties;
import java.util.logging.Logger;
​
public class MyDataSource1 implements DataSource {
    private Properties properties;
​
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
​
    @Override
    public String toString() {
        return "MyDataSource1{" +
                "properties=" + properties +
                '}';
    }
​
    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }
​
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }
​
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }
​
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
​
    }
​
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
​
    }
​
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }
​
    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
​
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }
​
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}

spring-util.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--引入命名空间
    在spring的配置文件头部添加:
    xmlns:util="http://www.springframework.org/schema/util"
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
​
    <util:properties id="ds">
        <prop key="driver">com.mysql.cj.jdbc.driver</prop>
        <prop key="url">jdbc:mysql://localhost:3306/spring</prop>
        <prop key="username">root</prop>
        <prop key="password">123</prop>
    </util:properties>
​
    <!--数据源1-->
    <bean id="ds1" class="com.hhb.jdbc.MyDataSource1">
        <property name="properties" ref="ds"/>
    </bean>
​
    <!--数据源2-->
    <bean id="ds2" class="com.hhb.jdbc.MyDataSource2">
        <property name="properties" ref="ds"/>
    </bean>
​
</beans>

4.7基于XML的自动装配

  • 都是基于set方法的。

4.7.1根据名称自动装配
<!--根据名字自动装配-->
    <bean id="orderServiceBean" class="com.hhb.service.OrderService" autowire="byName"/>
​
    <!--id一般也叫做bean的名称-->
    <!--bean的id不能随意写,set方法名去掉set,剩下的单词首字母小写-->
    <bean id="orderDao" class="com.hhb.dao.OrderDao"/>
4.7.2根据类型自动装配
<!--根据类型进行自动装配-->
<!--根据类型进行自动装配的时候,在有效的配置文件中,某种类型的使用只能有一个-->
<bean class="com.hhb.dao.VipDao"/>
<bean class="com.hhb.dao.UserDao"/>
<bean id="cs" class="com.hhb.service.CustomerService" autowire="byType"/>

4.8Spring引入外部属性配置文件

MyDataSource

package com.hhb.jdbc;
​
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
​
public class MyDataSource implements DataSource {
    private String driver;
    private String url;
    private String username;
    private String password;
​
    public void setDriver(String driver) {
        this.driver = driver;
    }
​
    public void setUrl(String url) {
        this.url = url;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    @Override
    public String toString() {
        return "MyDataSource{" +
                "driver='" + driver + '\'' +
                ", url='" + url + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
​
    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }
​
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }
​
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }
​
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
​
    }
​
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
​
    }
​
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }
​
    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
​
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }
​
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}

jdbc.properties

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring6
jdbc.username=root
jdbc.password=123

spring-properties.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--引入context命名空间-->
<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 http://www.springframework.org/schema/context/spring-context.xsd">
​
    <!--使用context:property-placeholder的location属性来指定属性配置文件的路径。
        location默认从类的根路径下开始加载资源-->
    <context:property-placeholder location="jdbc.properties"/>
​
    <!--配置数据源-->
    <bean id="ds" class="com.hhb.jdbc.MyDataSource">
        <property name="driver" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ja kar ta

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

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

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

打赏作者

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

抵扣说明:

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

余额充值