Java之旅Spring框架学习(2)——让你的编程变得“被动”

  上篇博客大致了解了Spring的一些知识,这次我们通过一个例子来了解Spring常用的两种注入方式构造器注入和setter注入。先看例子。

  因为spring是一个轻量级的框架与创建的项目类型无关,故而我们创建一个java项目即可。

 1.      示例演示

  新建一个Java Project

  建好的目录结构如下:


  很简单,此时我们需要为其添加相关的类和组件从而使得其变得丰富,添加完后的目录结构如下图:


  其中划线部分是我引入的关于Spring,以及单元测试,日志等等相关的jar包,如果你的程序出现问题,尤其是以java.lang.NoClassDefFoundError为首相关的错误,一般是缺少相关的jar,引入相关的jar即可。

  建立一个数据访问层的类,这里我们作为例子没有与数据库交互,主要是为了讲解Spring的相关,与hibernate以及Struts结合起来的使用我们在后面会讲到的。

   UserDao(数据访问层的接口)

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>package com.bjpowernode.spring.dao;

public interface UserDao {

	public void addUser(String username, String password);
}</strong></span>

  添加相应的实现这里我们采用Oracle和mysql两种实现,这样可以对比在Spring容器中数据库的灵活切换。

   UserDao4MySqlImpl(UserDao4OracleImpl)

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>public class UserDao4MySqlImpl implements UserDao {

	public void addUser(String username, String password) {
		System.out.println("UserDao4MySqlImpl.addUser()");
	}

}


public class UserDao4OracleImpl implements UserDao {

	public void addUser(String username, String password) {
		System.out.println("UserDao4OracleImpl.addUser()");
	}
}</strong></span>

  建立完数据访问层,再建立相应的服务层

   服务层接口(UserManager)

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>public interface UserManager {

	public void addUser(String username, String password);
}</strong></span>

   实现类(UserManagerImpl)

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>package com.bjpowernode.spring.manager;

import com.bjpowernode.spring.dao.UserDao;

public class UserManagerImpl implements UserManager {
	
	private UserDao userDao;
	
//	public UserManagerImpl(UserDao userDao) {
//		this.userDao = userDao;
//	}

	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}

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

}</strong></span>

   添加一个测试类Client

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>public class Client {

	public static void main(String[] args) {

		BeanFactory factory = new ClassPathXmlApplicationContext(
				"applicationContext.xml");

		// ApplicationContext factory = new
		// ClassPathXmlApplicationContext("applicationContext.xml");

		UserManager userManager = (UserManager) factory.getBean("userManager");

		// UserManager userManager = new UserManagerImpl(new
		// UserDao4MySqlImpl());

		userManager.addUser("张三", "123");
	}

}</strong></span>

   核心的配置文件(applicationContext.xml)

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><?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:tx="http://www.springframework.org/schema/tx"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  
  <bean id="userDao4Mysql" class="com.bjpowernode.spring.dao.UserDao4MySqlImpl"/>
  
  <bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
  
  <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
  	<!-- 
   	<constructor-arg ref="userDao4Mysql"/>
   	 -->
   	<!--  
   	<constructor-arg ref="usrDao4Oracle"/>
   	 -->
   	 <property name="userDao" ref="usrDao4Oracle"/>
  </bean>
</beans></strong></span>

 2.      示例知识点讲解

  配置文件的读取方式

   上篇博客我们已经讲解了存在两种方式读取配置文件,一个是使用BeanFactory,而另一种使用ApplicationContext。

         BeanFactory基本的工厂解析,管理,实例化所有容器内的bean的接口,spring中所有解析配置文件的类都直接或者间接实现该接口。              

          ApplicationContext接口implements BeanFactory

         创建对象的特点: BeanFactory在解析配置文件时并不会初始化对象,只有在使用对象时(getBean())才会对该对象进行初始化;ApplicationContext在解析配置文件时对配置文件中的所有对象都初始化了,getBean()方法只是获取对象的过程。

  注入的方式setter和构造器

  无论是构造器注入还是setter注入,都是一种依赖关系的注入,也就是将应用程序代码间的关系在配置文件中进行了描述,这里只是描述对象间的依赖关系或者业务逻辑的关系并不包含,但是并不创建相应的对象。

  好处就是应用DI原则后,代码将更加清晰。而且当bean自己不再担心对象之间的依赖关系(甚至不知道依赖的定义指定地方和依赖的实际类)之后,实现更高层次的松耦合将易如反掌。DI主要有两种注入方式,即Setter注入和构造器注入。

   构造器注入

   基于构造器的DI通过调用带参数的构造器来实现,每个参数代表着一个依赖。

   在上述代码的体现是:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>public class UserManagerImpl implements UserManager {
	
	private UserDao userDao;
	
	public UserManagerImpl(UserDao userDao) {
		this.userDao = userDao;
	}

	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
</strong></span>

   在配置文件中配置:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
  
  <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
   	<constructor-arg ref="userDao4Mysql"/>
  </bean>
</strong></span>

   延伸知识:

   对于类型匹配没有错误的,如下面的:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>package examples;

public class ExampleBean {

    // No. of years to the calculate the Ultimate Answer
    private int years;

    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}
</strong></span>

  该bean的构造参数类型已知,匹配也没有问题(跟前面的例子一样)。但是当使用简单类型时,比如<value>true<value>,Spring将无法知道该值的类型。不借助其他帮助,他将无法仅仅根据参数类型进行匹配。

  此时我们需要使用的是构造器参数类型匹配或者是构造参数索引。具体如下:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg type="int" value="7500000"/>
  <constructor-arg type="java.lang.String" value="42"/>
</bean>
  这是根据的参数类型。
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>
</strong></span>

  这是根据的索引。

   Setter注入

  通过调用无参构造器或无参static工厂方法实例化bean之后,调用该bean的setter方法,即可实现基于setter的DI。

  在代码中的使用:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>public class UserManagerImpl implements UserManager {
	
	private UserDao userDao;

public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
</strong></span>

   在配置文件中的配置:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
  
  <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
   	 <property name="userDao" ref="usrDao4Oracle"/>
  </bean>
</strong></span>

  配置访问数据库的数据源

  除了上述的setter属性注入和构造器注入之外,我们还可以使用属性进行相关的数据源的配置。

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  
  <!-- results in a setDriverClassName(String) call -->
  <property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
    <value>jdbc:mysql://localhost:3306/Spring_first</value>
  </property>
  <property name="username">
    <value>root</value>
  </property>
  <property name="password">
    <value>root</value>
  </property>
</bean></strong></span>

   也可以使用较为简洁的方式:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  
  <!-- results in a setDriverClassName(String) call -->
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="jdbc:mysql://localhost:3306/ Spring_first "/>
  <property name="username" value="root"/>
  <property name="password" value="root"/>
</bean>
</strong></span>

  数据访问层实现方式的灵活切换

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="userDao4Mysql" class="com.bjpowernode.spring.dao.UserDao4MySqlImpl"/>
  
  <bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
  
  <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
  	<!-- 
   	<constructor-arg ref="userDao4Mysql"/>
   	 -->
   	<!--  
   	<constructor-arg ref="usrDao4Oracle"/>
   	 -->
   	 <property name="userDao" ref="usrDao4Oracle"/>
  </bean>
</strong></span>

  我们只是需要更改ref指定的bean的唯一标识符id的值,即可实现灵活的切换,这样是不是很方便啊。

 3.      小结

  讲解完这些是不是明朗了很多呢!下篇咱们来说说容器是如何来管理你的bean,敬请期待~



评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值