Spring学习_day2

Spring入门实例

我们需要利用Spring来创建一个Bean对象,基本的步骤是:

  • 创建需要测试的类UserDao,UserDaoImpl,然后UserDaoImpl中实现接口UserDao的相关方法
  • 创建对应的配置文件xxx.xml(放在resource目录的下面)
  • 在上面的配置文件中,我们通过这个语句<bean id="需要实例化对象的id,是我们任意取得,但是需要唯一,因为id是唯一的" class="需要实例化的对象的路径"></bean>
  • 在测试得方法中,通过Spring客户端调用getBean方法来获取实例化Bean对象

对应得代码为:

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    public UserDaoImpl(){
        System.out.println("UserDaoImpl实例化.........");
    }

    public void init(){
        System.out.println("UserDaoImpl is initing..........");
    }

    public void destroy(){
        System.out.println("UserDaoImpl is destroying...........");
    }
    @Override
    public void save() {
        System.out.println("save is running........");
    }
}

//测试类
public class UserDaoTest {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
        //application调用getBean方法,来获取id为UserDaoImpl的对象
        UserDao userDao = application.getBean("UserDaoImpl", UserDao.class);
        System.out.println(userDao);
        userDao.save();
    }
}

对应的配置文件application.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="UserDaoImpl" class="day2.demo.dao.impl.UserDaoImpl"></bean>
</beans>

运行结果为:
在这里插入图片描述

而之所以先执行UserDaoImpl中的无参构造方法的操作,是因为<bean></bean>中默认的是通过无参构造方法进行实例化的。而在Spring中实例化Bean对象主要有3中方法:

  1. 无参构造方法实例化(主要的)

  2. 工厂静态方法实例化:因为是静态方法,所以可以通过类名来调用对应的方法来获取需要实例化的Bean对象。因此不需要在调用相应的方法之前来实例化工厂。通过这一种方式来实例化bean对象的时候,我们需要将上面的配置文件中的 <bean id="UserDaoImpl" class="day2.demo.dao.impl.UserDaoImpl"></bean>修改为:<bean id="UserDaoImpl" class="对应的工厂的路径" factory-method="相应的方法之后就可以获取想要的Bean对象"></bean>,因此修改之后为:<bean id="UserDaoImpl" class="day2.demo.factory.StaticFactory" factory-method="getUserDaoImpl"></bean>

    对应的application.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="UserDaoImpl" class="day2.demo.factory.StaticFactory" factory-method="getUserDaoImpl"></bean>
    </beans>
    

    对应的StaticFactory代码为:

    public class StaticFactory {
        public static UserDaoImpl getUserDaoImpl(){
            return new UserDaoImpl();
        }
    }
    
  3. 工厂动态方法实例化:所谓的动态,就是工厂中的方法并不是静态的,所以我们要执行工厂的对应方法之前,我们需要先实例化工厂,然后再执行对应的方法,来获取想要的Bean实例化对象,所以修改之后的application.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="factory" class="day2.demo.factory.DynamicFactory"></bean><!--实例化工厂-->
          <bean id="UserDaoImpl" factory-bean="factory" factory-method="getUserDaoImpl"></bean><!--通过factory-bean,从而可以知道当前要实例化的bean对象将从这个factory中的getUserDaoImpl方法获得-->
    </beans>
    

    对应的DynamicFactory代码为:

    public class DynamicFactory {
        public UserDaoImpl getUserDaoImpl(){
            return new UserDaoImpl();
        }
    }
    
    

其中的<bean></bean>中含有几个属性需要说明一下的是:

  • scope:说明这个bean对象的域,它的值可以是:singleton,prototype,request,session,global session. 而我们重点来说前面2个值的情况。如果scope的值为singleton,那么说明这个bean实例化对象在Spring容器中只有1个,并且它是在加载核心配置文件创建的,也就是执行new ClassPathXmlApplicationContext("application.xml")的时候就创建的,所以这个bean对象在Spring容器只有1个,并且在配置文件加载的时候被实例化的;而如果scope的值为prototype的话,那么这个bean实例化对象可以在Spring容器中有多个,因为它是在Spring客户端调用getBean方法的时候实例化的。对应的application.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">
        <!--
         scope的值为singleton,那么Spring容器中只有一个UserDaoImpl实例化对象
         并且是在加载这个配置文件的时候实例化的
         -->
    <bean id="UserDaoImpl" class="day2.demo.dao.impl.UserDaoImpl" scope="singleton"></bean>
    </beans>
    

    测试类代码:

    public interface UserDao {
        public void save();
    }
    
    public class UserDaoImpl implements UserDao {
        public UserDaoImpl(){
            System.out.println("UserDaoImpl实例化.........");
        }
    
        public void init(){
            System.out.println("UserDaoImpl is initing..........");
        }
    
        public void destroy(){
            System.out.println("UserDaoImpl is destroying...........");
        }
        @Override
        public void save() {
            System.out.println("save is running........");
        }
    }
    
    //测试类
    public class UserDaoTest {
        public static void main(String[] args) {
            /*
            因为scope的值是singleton,所以只有spring容器中只有1个UserDaoImpl实例化对象
            因此userDao1和userDao2的地址是相同的,所以最后输出的是true
            */
            ApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
            UserDao userDao1 = application.getBean("UserDaoImpl", UserDao.class);
            UserDao userDao2 = application.getBean("UserDaoImpl", UserDao.class);
            System.out.println(userDao1);
            System.out.println(userDao2);
            System.out.println(userDao1 == userDao2); //true
           
        }
    }
    

    运行结果:
    在这里插入图片描述

    如果scope的值为prototype,那么就会在getBean方法的时候,进行实例化,所以得到的实例化对象的地址不一样。我们将application.xml中的scope的值修改为prototype之后,对应的运行结果为:
    在这里插入图片描述

  • init-method:生命周期方法,在进行初始化的时候,就会执行这个方法.所以我们只需要在<bean></bean>中添加这个属性,那么在实例化之后,就会执行这个值所对应的方法进行初始化.

  • destroy-method:生命周期方法,当要销毁这个对象的时候,就会先执行这个方法,然后在销毁。但是一般不可以在后台看到这个方法的执行内容,所以我们需要手动关闭Spring客户端,之后就可以看到了.

    对应的application.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">
        <!--init-method指明初始化方法为init,destroy-method指明销毁方法为destroy-->
    <bean id="UserDaoImpl" class="day2.demo.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
    </beans>
    

    测试类代码为:

    public interface UserDao {
        public void save();
    }
    
    public class UserDaoImpl implements UserDao {
        public UserDaoImpl(){
            System.out.println("UserDaoImpl实例化.........");
        }
    
        public void init(){
            System.out.println("UserDaoImpl is initing..........");
        }
    
        public void destroy(){
            System.out.println("UserDaoImpl is destroying...........");
        }
        @Override
        public void save() {
            System.out.println("save is running........");
        }
    }
    
    //测试类
    public class UserDaoTest {
        public static void main(String[] args) {
            //因为ApplicationContext是一个接口,所以不可以直接执行close,而
            //ClassPathXmlApplicationContext则是它的实现类
            ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
            //application调用getBean方法,来获取id为UserDaoImpl的对象
            UserDao userDao = application.getBean("UserDaoImpl", UserDao.class);
            System.out.println(userDao);
            userDao.save();
            //手动关闭spring客户端,这时候就会在spring关闭之前,先将userDao销毁
            application.close();
           
        }
    }
    

    运行结果为:
    在这里插入图片描述

Spring中Bean的依赖注入

bean对象的依赖注入

测试的准备:我们需要创建2个接口:UserDao,UserService,并且两个接口中都有save方法,同时创建对应的实现类:UserDaoImpl,UserServiceImpl,都实现了save。其中UserServiceImpl中的save方法是通过UserDao来调用save方法来实现的。

那么如果没有利用Spring的话,我们应该是这样写的:

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("UserDaoImpl save is running.....");
    }
}

public interface UserService {
    public void save();
}

public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
    @Override
    public void save() {
        userDao.save();
    }
}

//测试类
public class UserTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.save();
    }
}

然后我们通过spring,这样就需要我们利用new来创建实例化对象,对应的application.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"
       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">
       <bean id="userDao" class="day3.demo.dao.impl.UserDaoImpl"></bean>
       <bean id="userService" class="day3.demo.service.impl.UserServiceImpl"></bean>
</beans>

这样spring容器中就有了userDao,userService这2个实例化对象,然后再通过getBean来获取这些实例化对象即可.所以对应的代码为(只需要修改UserServiceImpl中的save方法以及测试类中的方法即可):

public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        ApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
        UserDao userDao = application.getBean("userDao", UserDao.class);
        userDao.save();
    }
}

//测试类
public class UserTest {
    public static void main(String[] args) {
       ApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
       UserService userService = application.getBean("userService", UserService.class);
       userService.save();
    }
}

但是这样Spring容器中2个bean对象却是没有任何的关系的,但是我们如果需要UserDao依赖于UserService,也即UserService中含有UserDao这个成员,那么此时我们又该怎样通过spring来实现呢?这时候就需要利用到了bean的依赖注入了。此时有2中方式可以实现依赖的注入:

  • 通过set方法实现Bean的依赖注入:我们只需要修改application.xml中的<bean id="userService" class="day3.demo.service.impl.UserServiceImpl"></bean>即可,因为UserServiceImpl中含有属性UserDao,那么我们只要给这个属性赋值即可.所以修改之后的application代码为:

    <?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="userDao" class="day3.demo.dao.impl.UserDaoImpl"></bean>
        <!--
        可以利用P命名空间来代替下面的代码,只是我们需要再上面的beans中添加这一行:
        xmlns:p="http://www.springframework.org/schema/p"  即可
        <bean id="userService" class="day3.demo.service.impl.UserServiceImpl" 
              p:userDao-ref="userDao"></bean>
        同样的userDao-ref中,首先userDao指明的是UserServiceImpl中的成员userDao,ref则是
        指明希望将id为userDao这个bean对象赋值给属性成员userDao
         -->
        <bean id="userService" class="day3.demo.service.impl.UserServiceImpl">
            <!--property中,第一个userDao是UserServiceImpl中的属性成员的名字,ref则是指明bean对象的id,
                即希望将哪一个bean对象赋值给UserServiceImpl中的对应成员
            -->
            <property name="userDao" ref="userDao"></property>
        </bean>
    </beans>
    

    因为是通过set方法进行赋值的,所以我们需要保证UserServiceImpl这个类中含有set方法,并且是设置UserDao的值,对应的UserServiceImpl代码为:

    public class UserServiceImpl implements UserService {
        private UserDao userDao;
        public void setUserDao(UserDao userDao){
            this.userDao = userDao;
        }
        @Override
        public void save() {
            userDao.save();
        }
    }
    
    
  • 通过有参构造方法实现Bean的依赖注入,那么我们需要修改application.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"
           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">
        <bean id="userDao" class="day3.demo.dao.impl.UserDaoImpl"></bean>
        <bean id="userService" class="day3.demo.service.impl.UserServiceImpl">
            <!--constructor-arg指明了构造方法的参数,参数名为userDao,并且ref
                指明了将id为userDao的bean对象赋值给这个参数
            -->
            <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        </bean>
    </beans>
    

    所以通过有参构造方法来实现依赖注入的时候,要求UserServiceImpl拥有对应的有参构造方法:

    public class UserServiceImpl implements UserService {
        private UserDao userDao;
        public UserServiceImpl(UserDao userDao) {
            this.userDao = userDao;
        }
        @Override
        public void save() {
            userDao.save();
        }
    }
    
    

数据类型的依赖注入

如果是int,double,String这些类型的依赖注入,那么我们可以同样可以通过set来实现依赖注入,通过<property name="成员名字" value="成员的值"></property>,通过比较可以发现,如果是通过set来实现bean对象的依赖注入,它是ref,否则,那么就是通过value来赋值的

集合等类型的依赖注入

如果是List,HashMap,Properties这些类型的依赖注入,那么我们同样可以通过set来实现依赖注入,对应的application.xml中代码为:

<bean id="user" class="day3.demo.domain.User">
    <!--对User这个类中的List<String>进行依赖注入,成员名为list-->
    <property name="list">
        <list>
            <!--如果list中的元素不是bean对象,那么使用的是value,否则,用的是ref-->
            <value>xxx</value>
            <ref bean="xxxx"></ref> <!--list中的元素是bean对象,其中bean属性的值就是对应的bean对象id-->
        </list>
    </property>
    <!--给User这个类中的HashMap<xxx,xxx>进行依赖注入,成员名为map-->
    <property name="map">
        <map>
            <!--
             因为map中的元素是一个键值对,所以使用的是entry,如果key不是bean对象,那么单纯是key,
             否则,如果key是bean对象,那么应该是key-ref,同样的,如果value不是bean对象,那么
             单纯是value,否则,value是bean对象,那么应该是value-ref
            -->
            <entry key="xxx" value="xxxx"></entry> <!--key,value都不是bean对象的情况下-->
            <entry key-ref="xxx" value="xxxx"></entry><!--key是bean对象,value不是bean对象的情况下-->
            <entry key="xxx" value-value="xxxx"></entry><!--key不是bean对象,value是bean对象的情况下-->
            <entry key-ref="xxx" value-ref="xxxx"></entry><!--key,value都是bean对象的情况下-->
        </map>
    </property>
    <!--给User这个类中的Properties进行依赖注入,成员名为props-->
    <property name="props">
        <props>
            <!--propertiest中的元素是一个键值对,只是都是String类型,所以没有key-ref的形式-->
            <prop key="xxx">对应的值</prop>
        </props>
    </property>
</bean>

对应的代码为:

public class User {
    private String name;
    private Integer age;
    private int id;
    private List<Object> strList;
    private Map<String,Score> map;
    private Properties props;
    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public List<Object> getStrList() {
        return strList;
    }

    public void setStrList(List<Object> strList) {
        this.strList = strList;
    }

    public Map<String, Score> getMap() {
        return map;
    }

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

    public Properties getProps() {
        return props;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        System.out.println("strList = " + strList);
        System.out.println("map = " + map);
        System.out.println("props = " + props);
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}

//测试类
public class UserTest2 {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
        User user = application.getBean("user", User.class);
        System.out.println(user);
    }
}

对应的application.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"
       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">

       <!--数据类型的依赖注入:同样是有构造方法和set注入2中方式,
           但是set注入方式居多。此时使用的语句应该是<property name="field_name" value="field_value"></property>
           使用的是value,而不是ref,ref用于bean对象的依赖注入
       -->
       <bean id="user" class="day3.demo.domain.User">
              <property name="name" value="zhangshan"></property>
              <property name="age" value="18"></property>
              <property name="id" value="1"></property>
              <property name="strList">
                     <list>
                            <value>aaa</value>
                            <value>bbb</value>
                            <value>ccc</value>
                            <ref bean="score1"></ref>
                     </list>
              </property>
              <property name="map">
                     <map>
                            <entry key="score1" value-ref="score1"></entry>
                            <entry key="score2" value-ref="score2"></entry>

                     </map>
              </property>
              <property name="props">
                    <props>
                           <prop key="prop1">aaa</prop>
                           <prop key="prop2">bbb</prop>
                    </props>
              </property>
       </bean>

       <bean id="score1" class="day3.demo.domain.Score">
              <property name="name" value="语文"></property>
              <property name="goal" value="90.5"></property>
       </bean>

       <bean id="score2" class="day3.demo.domain.Score">
              <property name="name" value="数学"></property>
              <property name="goal" value="95.5"></property>
       </bean>

</beans>

运行结果为:
在这里插入图片描述

⭐⭐⭐通过set来进行依赖注入的时候,需要保证类中有setXXX的方法;通过有参构造方法来进行依赖注入的时候,需要保证有对应的有参构造方法

Spring配置数据源

普通配置数据源的基本步骤是:

  1. 导入相应的依赖到pom.xml中,例如我们需要配置druid数据源,那么我们就需要先导入druid数据源的依赖。

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.3</version>
    </dependency>
    
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.5</version>
    </dependency>
    
    
    
  2. 创建对应的数据源对象,例如new DruidDataSource()

  3. 设置连接数据库的基本信息,即driverClass,url,user,password

  4. 数据源对象调用getConnection方法,来获取连接对象Connection

  5. 归还Connection

导入相应的依赖之后,对应的代码为:

public class DataSourceTest {
   @Test
   public void test2() throws Exception {
       DruidDataSource dataSource = new DruidDataSource();
       dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
       dataSource.setUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai");
       dataSource.setUsername("root");
       dataSource.setPassword("root");
       DruidPooledConnection connection = dataSource.getConnection();
       System.out.println(connection);
       //归还数据源
       connection.close();
   }
    
    @Test
    public void test1() throws Exception {
        //创建ComboPooledDataSource
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //设置连接信息
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //归还Connection
        connection.close();
    }
}

如果我们需要将连接数据库的基本信息放到了一个配置文件jdbc.properties中,然后我们需要设置的时候,只需要读取这个配置文件即可。所以通过ResourceBundle来进行读取,获取对应键的值。之后就可以直接利用XXXDataSource对象来设置了。所以DataSourceTest对应的代码为:

public class DataSourceTest {
   /*
   通过读取jdbc.properties配置文件来设置driverClass,url,username,
   password这些信息。
   基本步骤:
   1.读取jdbc.properties ---> 获取ResourceBundle对象,通过
   静态方法getBundle来获得,传递的参数就是jdbc(即xxx.properties
   的文件名,不需要后缀)
   2.获取properties文件中的对应key的值
   3.设置信息
    */
   @Test
   public void test4() throws Exception {
       ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
       String driver = resourceBundle.getString("driver");
       String url = resourceBundle.getString("url");
       String username = resourceBundle.getString("user");
       String password = resourceBundle.getString("password");
       //创建Druid连接池
       DruidDataSource dataSource = new DruidDataSource();
       dataSource.setDriverClassName(driver);
       dataSource.setUrl(url);
       dataSource.setUsername(username);
       dataSource.setPassword(password);
       //获取Connection对象
       DruidPooledConnection connection = dataSource.getConnection();
       System.out.println(connection);
       //归还Connection对象
       connection.close();
   }
   @Test
   public void test3() throws Exception {
       ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
       String driver = resourceBundle.getString("driver");
       String url = resourceBundle.getString("url");
       String username = resourceBundle.getString("user");
       String password = resourceBundle.getString("password");
       //创建数据源对象
       ComboPooledDataSource dataSource = new ComboPooledDataSource();
       dataSource.setDriverClass(driver);
       dataSource.setJdbcUrl(url);
       dataSource.setUser(username);
       dataSource.setPassword(password);
       //获取链接对象Connection
       Connection connection = dataSource.getConnection();
       System.out.println(connection);
       //归还Connection
       connection.close();
   }

}

对应的jdbc.properties文件为:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai
user=root
password=root

而上面中,需要利用new来创建xxxDataSource对象,那么这个过程我们可以交给Spring来进行实例化,而获取对应的DataSource对象之后,还需要通过dataSource对象调用对应的set方法来设置相关的属性,那么我们也可以利用spring来进行依赖注入,所以对应的application.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="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

    <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
</beans>

完成上面的步骤之后,我们再利用spring调用getBean方法返回DataSource对象的时候,我们已经设置了user,password,url,driverClass这4个基本信息,所以可以直接调用getConnection来获取Connection对象了.对应的DataSourceTest代码为:

public class DataSourceTest {
 
   @Test
   public void test6() throws Exception{
       ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
       DruidDataSource druidDataSource = application.getBean("druid", DruidDataSource.class);
       DruidPooledConnection connection = druidDataSource.getConnection();
       System.out.println(connection);
       connection.close();
   }

   @Test
    public void test5() throws Exception{
       ApplicationContext application = new ClassPathXmlApplicationContext("application.xml");
       ComboPooledDataSource dataSource = application.getBean("c3p0", ComboPooledDataSource.class);
       Connection connection = dataSource.getConnection();
       System.out.println(connection);
       //归还connection
       connection.close();
   }
  
}

但是这时候我们并没有充分利用到jdbc.properties这个配置文件。而在Spring中,要加载properties文件,那么我们需要利用context命名空间.对应的application.xml只需要修改beans标签,添加了:xmlns:context="http://www.springframework.org/schema/context"这一行,同时xsi:schemaLocation的值也添加了http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd.
经过上述的操作之后,就可以使用context命名空间了,然后利用<context:properties-placeholder location="jdbc.properties"></context:properties-placeholder>就可以导入jdbc.properties文件了。然后我们利用spring表达式${xxx}来获取jdbc.properties中key为xxx的值了,对应的代码为:

<?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 http://www.springframework.org/schema/context/spring-context.xsd">
    <!--
application.xml中加载properties文件的基本步骤:
利用的是context命名空间,我们需要在beans中添加
xmlns:context="http://www.springframework.org/schema/context"
同时还需要添加约束路径,直接将xsi:schemaLocation中的值复制一遍,然后将其中的
beans改成context即可

然后我们可以直接利用context命名空间来导入properties文件了
location就是我们要导入的properties文件
<context:property-placeholder location="classpath:jdbc.properties"><context:property-placeholder>
 然后利用spring表达式${xx},就可以获取properties文件中key为xx的值了
-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${driver}"></property>
        <property name="jdbcUrl" value="${url}"></property>
        <!--值得注意的是,这里的jdbc.properties中的user的键不可以是
        username,否则,就会默认读取的是电脑用户作为数据库的user,所以只需要
        将键username改为其他字符串即可-->
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driver}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>
  
</beans>

值得注意的是,如果jdbc.properties中的key为username的话,那么就会导致连接数据源发生错误,因为它是读取了电脑用户作为user,所以我们不可以使用username作为jdbc.properties中的键.,下面是jdbc.properties文件内容:
在这里插入图片描述

如果我们将上面的user改成了username,然后将application.xml中的${user}改成${username}之后,那么运行的时候,就会发生以下错误,就是因为他将电脑作为了数据库的用户,从而导致错误的,因此jdbc.properties中的用户名的key不可以是username:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值