SSM框架-spring中bean的依赖注入

4 依赖注入方式

4.1 概述

  1. 依赖注入描述容器中bean和bean中之间的依赖关系的过程,如果bean运行需要的是数字或者字符串呢?
  • 引用类型
  • 简单类型(基本数据类型String)
  1. 类型
  • setter类型
    • 简单类型
    • 引用类型
  • 构造器注入
    • 简单类型
    • 引用类型

4.2 setter注入

  1. 引用数据类型多个bean的依赖
  • 接口UserDao
public interface UserDao {
    public void save();
}
  • 接口BookDao
public interface BookDao {
    void save();
}
  • 接口BookService
public interface BookService {
    void save();
}
  • 接口实现类UserDaoImpl
public class UserDaoImpl implements UserDao{
    public void save(){
        System.out.println("user dao save ...");
    }
}
  • 接口实现类BookDaoImpl
public class BookDaoImpl implements BookDao{
    public void save(){
        System.out.println("book dao save");
    }
}
  • 接口实现类**[重点]**
public class BookServiceImpl implements BookService {
    //删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;
    private UserDao userDao;


    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    //生成set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }


    public void save(){
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}
  • 配置文件
        <bean id ="bookDao" name = "dao" class = "com.itheima.dao.impl.BookDaoImpl"  scope="prototype"/>
        <bean id = "userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

        <bean id = "bookService" name = "service bookEbi" class = "com.itheima.service.impl.BookServiceImpl">
                <property name="bookDao" ref="bookDao"/>
                <property name="userDao" ref="userDao"/>
        bean>
  • App类
public class App2 {
    public static void main(String[] args) {
        //3.获取IoC容器,ApplicationContext和配置一样,new一个接口实现类
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}
  • 打印结果
book service save ...
book dao save
user dao save ...

Process finished with exit code 0
  1. 简单类型
  • 接口实现类BookDaoImpl
public class BookDaoImpl implements BookDao{

    private int connectionNum;
    private String databaseName;

    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
    

    public void save(){
        System.out.println("book dao save"+databaseName+","+connectionNum);
    }
}
  • 配置文件
        <bean id ="bookDao" name = "dao" class = "com.itheima.dao.impl.BookDaoImpl">
                <property name="databaseName" value="mysql"/>
                <property name="connectionNum" value="10"/>
        bean>
  • 打印结果
book service save ...
book dao savemysql,10
user dao save ...

Process finished with exit code 0

4.3 构造器注入

  1. 引用数据类型
  • 接口实现类BookDaoImpl
public class BookDaoImpl implements BookDao{

    public void save(){
        System.out.println("book dao save");
    }
}
  • 接口实现类UserDaoImpl
public class UserDaoImpl implements UserDao{
    public void save(){
        System.out.println("user dao save ...");
    }
}
  • 接口实现类BookServiceImpl【更改之处】
public class BookServiceImpl implements BookService {
    //删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;
    private UserDao userDao;
    //private BookDao bookDao = new BookDaoImpl();

    //去掉setter方法,进行构造方法构造依赖,记得整两

    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }

    public void save(){
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}
  • App入口
public class App2 {
    public static void main(String[] args) {
        //3.获取IoC容器,ApplicationContext和配置一样,new一个接口实现类
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}
  • 配置文件【更改之处】
        <bean id ="bookDao" name = "dao" class = "com.itheima.dao.impl.BookDaoImpl"/>
        <bean id ="userDao" name = "dao" class = "com.itheima.dao.impl.UserDaoImpl"/>
        <bean id = "bookService" class = "com.itheima.service.impl.BookServiceImpl">
                <constructor-arg name="bookDao" ref="bookDao"/>
                <constructor-arg name="userDao" ref="userDao"/>
        bean>

这边的name表示构造器的形参

  1. 简单类型
  • 实现接口类BookDaoImpl

也是用的构造器实现的

public class BookDaoImpl implements BookDao{

    private String databaseName;
    private int connectionNum;

    public BookDaoImpl(String databaseName, int connectionNum) {
        this.databaseName = databaseName;
        this.connectionNum = connectionNum;
    }

    public void save(){
        System.out.println("book dao save"+databaseName+connectionNum);
    }
}
  • 配置文件

这两顺序可以换

        <bean id ="bookDao" class = "com.itheima.dao.impl.BookDaoImpl">
                <constructor-arg name="databaseName" value="mysql"/>
                <constructor-arg name="connectionNum" value="666"/>
        bean>
  • 运行结果
book service save ...
book dao savemysql666
user dao save ...

Process finished with exit code 0
  1. 优化构造器
  • 类型指定

如果构造器的形参变了,配置文件就得重新配置,出现耦合度比较高的情况,

因此可以直接写类型,不直接指定形参

        <bean id ="bookDao" class = "com.itheima.dao.impl.BookDaoImpl">
                <constructor-arg type="java.lang.String" value="mysql"/>
                <constructor-arg type="int" value="10"/>
        bean>
  • 位置指定

但是也可能出现两种类型一样的形参

于是出现了通过index需要指定

        <bean id ="bookDao" class = "com.itheima.dao.impl.BookDaoImpl">
                <constructor-arg index="0" value="mysql"/>
                <constructor-arg index="1" value="100"/>
        bean>
  • 其他

4.4 总结

SSM框架-spring中bean的依赖注入_第1张图片

  • 构造器注入必须强制执行,setter可以执行也可以不执行

5 依赖自动装配

5.1 概念

IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

5.2 种类

  1. 按类型
  2. 按名称
  3. 按构造方法
  4. 不启动自动装配

5.3 实践

5.3.1 按照byType匹配

  1. 具体设置
  • 接口实现类BookServiceImpl

依旧记得保留setter方法

public class BookServiceImpl implements BookService {
    //删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;
//    private BookDao bookDao = new BookDaoImpl();

    //生成set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}
  • 配置文件

加上autowire就可以了

        <bean id ="bookDao" class = "com.itheima.dao.impl.BookDaoImpl"  scope="prototype"/>

        <bean id = "bookService"
              class = "com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
  1. 注意点
  • 报错1

SSM框架-spring中bean的依赖注入_第2张图片

SSM框架-spring中bean的依赖注入_第3张图片

image.png

BookServiceImpl中的BookDao与配置文件中的bookDao中bean实现了Dao接口,如果没有就报错

也就是说是private BookDao bookDao中的BookDao 和

  • 报错2

SSM框架-spring中bean的依赖注入_第4张图片

image.png

如果满足接口的Dao接口的有两个,就会装配失败

5.3.2 按照byName匹配

  1. 匹配原则

SSM框架-spring中bean的依赖注入_第5张图片

SSM框架-spring中bean的依赖注入_第6张图片

private BookDao bookDao中的bookDao和id ="bookDao"中的bookDao名字要一样,耦合度较高

  1. 配置文件内容

autowire="byName

        <bean id ="bookDao" class = "com.itheima.dao.impl.BookDaoImpl"  scope="prototype"/>

        
        <bean id = "bookService" class = "com.itheima.service.impl.BookServiceImpl" autowire="byName"/>

5.3.3 总结

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 按类型匹配byType保证容器中相同类型的bean唯一,推荐使用
  • 使用按名称配对byName保证容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

6 集合注入

6.1 内容

  1. 数组
  2. List
  3. Set
  4. Map
  5. Propertites

6.2 配置内容

  1. BookDaoImpl接口实现类
public class BookDaoImpl implements BookDao{

    private int[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties properties;


    public void setArray(int[] array) {
        this.array = array;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void save(){
        System.out.println("book dao save");
        System.out.println("遍历数组:"+ Arrays.toString(array));
        System.out.println("遍历List:"+list);
        System.out.println("遍历Set:"+set);
        System.out.println("遍历Map:"+map);
        System.out.println("遍历Properties:"+properties);
    }
}
  1. 配置文件
        <bean id ="bookDao" name = "dao" class = "com.itheima.dao.impl.BookDaoImpl">

                <property name="array">
                   <array>
                        <value>100</value>
                        <value>200</value>
                        <value>300</value>
                       <ref bean="beanId"/>
                   </array>
                </property>

                <property name="list">
                   <list>
                         <value>itcast</value>
                         <value>itheima</value>
                         <value>boxuegu</value>
                         <value>chuanzhihui</value>
                   </list>
                </property>

                <property name="set">
                  <set>
                         <value>itcast</value>
                         <value>itheima</value>
                         <value>boxuegu</value>
                  </set>
                </property>

                <property name="map">
                   <map>
                        <entry key="country" value="china"/>
                        <entry key="province" value="guangdong"/>
                        <entry key="city" value="guangzhou"/>
                    </map>
                </property>

            <property name="properties">
                <props>
                    <prop key="country">china</prop>
                    <prop key="province">guangdong</prop>
                    <prop key="city">guangzhou</prop>
                </props>
            </property>
        </bean>

7 第三方bean注入:以数据源对象管理为例

7.1 概述

第三方的bean该如何管理

7.2 Druid管理

  1. pom中进行maven文件配置

Druid是阿里巴巴开发的数据连接池

    <dependency>
      <groupId>com.alibabagroupId>
      <artifactId>druidartifactId>
      <version>1.1.16version>
    dependency>
  1. 判断使用setter还是构造器方法

image.png

SSM框架-spring中bean的依赖注入_第7张图片

发现DruidDataSource中有setter方法

  1. 配置文件进行配置
        
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        bean>
  1. App入口
public class App2 {
    public static void main(String[] args) {
        //3.获取IoC容器,ApplicationContext和配置一样,new一个接口实现类
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
        
    }
}
  1. 结果
{
	CreateTime:"2022-11-06 23:08:56",
	ActiveCount:0,
	PoolingCount:0,
	CreateCount:0,
	DestroyCount:0,
	CloseCount:0,
	ConnectCount:0,
	Connections:[
	]
}

7.3 C3P0连接池管理

  1. mvnrepository中获取配置
  • C3P0

网址:去Maven Repository: c3p0 » c3p0 » 0.9.1.2 (mvnrepository.com)复制代码


<dependency>
    <groupId>c3p0groupId>
    <artifactId>c3p0artifactId>
    <version>0.9.1.2version>
dependency>
  • mysql

网址:Maven Repository: mysql » mysql-connector-java » 5.1.16 (mvnrepository.com)


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.16version>
dependency>
  1. 加载到maven中
<dependency>
    <groupId>c3p0groupId>
    <artifactId>c3p0artifactId>
    <version>0.9.1.2version>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.16version>
dependency>
  1. 使用setter注入
  • 配置文件
        <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">

            <property name="driverClass" value="com.mysql.jdbc.Driver"/>
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_db"/>
            <property name="user" value="root"/>
            <property name="password" value="root"/>
  • App入口
public class App2 {
    public static void main(String[] args) {
        //3.获取IoC容器,ApplicationContext和配置一样,new一个接口实现类
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource2");
        System.out.println(dataSource);
    }
}
  • 结果
com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge1adasl3sdda8tlh5w|76b0bfab, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge1adasl3sdda8tlh5w|76b0bfab, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/spring_db, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]

8 加载properties文件

8.1 概述

  1. jbdc.properties配置文件

image.png

  1. 需求

需要让spring可以读取识别properties的文件

8.2 操作

  1. 配置文件中开辟新的空间

SSM框架-spring中bean的依赖注入_第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
                http://www.springframework.org/schema/context/spring-context.xsd
                ">
  1. 加载properties文件
  • 开辟属性占位符,并确定properties的位置
  • 使用${}改变value的值,并读取properties文件中的属性
    
    
    <context:property-placeholder location="jdbc.properties"/>

    
    <bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    bean>
  1. 将读出来的值放到name中
  • jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root
  • 配置文件增加这一个
    
    <bean id = "bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <property name="name" value="${jdbc.driver}"/>
    bean>
  • App实现类
public class App2 {
    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();

    }
}
  • 结果
book dao savecom.mysql.jdbc.Driver

Process finished with exit code 0
  1. 注意
  • 如果有多个配置文件都要加载

SSM框架-spring中bean的依赖注入_第9张图片

可以用,或者用*

SSM框架-spring中bean的依赖注入_第10张图片

使用classpath表示类路径

SSM框架-spring中bean的依赖注入_第11张图片

使用classpath*表示可以从本工程,或者以及依赖的jar包中读取

SSM框架-spring中bean的依赖注入_第12张图片

你可能感兴趣的:(spring,bean,Driud)