您的位置:首页 > 编程语言 > Java开发

Spring入门+简单原理

2011-10-13 13:51 302 查看
还是先上一个简单的代码段再来说明问题:

package com.akwolf.spring.common;

public class CommonSimple {
	public int compute(int i, int j) {
		return i + j;
	}
}


package com.akwolf.spring.common;

public class UserSimple {

	public static void main(String[] args) {
		CommonSimple commonSimple = new CommonSimple() ;
		
		System.out.println(commonSimple.compute(5, 8));
	}
}


通常情况下,我们要使用一个类就是在需要的地方直接采用new关键字,创建对象然后调用方法,一切看上去so perfect,代码也运行的很正常,但在想长远一点,若以后需求发生改变,main方法中要使用乘法进行进行计算,那就得修改代码,创建有乘法方法的对象,少量的代码,没问题,我挨着手动的改,当代码量巨大的时候,嘿嘿,,噩梦开始了。另一个方面,好的OO编程思想是要符合开闭原则,即对修改关闭,对拓展开放。要降低耦合................

,反正就一大堆啦,,这个时候引入spring看一下。

一、Spring的主要思想。我就不罗嗦了,控制反转(IOC、DI),面向接口编程,google一下讲解的很多。

二、搭建一个Spring的开发环境。

1、对于没有特殊需求加入spring.jar和commons-logging.jar就已足够,使用eclipse时build path一下就ok。

2、在src目录下建一个beans.xml ,对要使用的到类,进行管理,,这就降低了耦合,在使用的使用不在使用new关键字了,贴一下配置文件。

<?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-2.5.xsd"> 	<!-- 初始化sample实现类 -->
	<bean
		id="sample"
		class="com.akwolf.spring.impl.SampleImpl" />
</beans>


这时再来看一下,再怎么使用(在Junit中编写的代码,自己测试时要引入junit的库)

private static ApplicationContext context ;
	@BeforeClass
	public static void init(){
		context = new ClassPathXmlApplicationContext("beans.xml") ;
	}

	@Test
	public void testCompute() {
		Sample sample = (Sample) context.getBean("sample") ;
		System.out.println(sample.compute(5, 6)); 
	}


情况看上去好了一点,好吧,再来一个深入一点点的例子,讲解一下对IOC、面向接口编程的理解。

三、进一步理解spring

现在需求是要提供一个类要从一个数据源中取得全部书籍的数据、可能是开始就初始化好的数据、可能是从本地文件中读取、可能是从数据库中读取,可能是。。。。,很多可能是的说。还有一个类是给客户端程序调用来查询相应的书籍的详细信息的类,这个类的实现也是很多中方法了。那肿么办?那就面向接口编程呗,定义好接口,管你怎么实现,客户端只调用接口里面的方法就行。好,开始贴代码说明问题。

定义一个查询数据源的接口就叫他BookFinder.java

package com.akwolf.spring;

import java.util.List;

import com.akwolf.bean.Book;

public interface BookFinder {
	/**
	 * 定义查询数据源的方法
	 * @return
	 */
	public List<Book> findAll() ;
}


定义给客户端调用查询的接口BookLister.java

package com.akwolf.spring;

import java.util.List;

import com.akwolf.bean.Book;

public interface BookLister {
	/**
	 * 根据书名查找所有的书籍
	 * 
	 * @param name
	 * @return
	 */
	public List<Book> findBook(String name);
}


ok、接口定义完成之后开始进行实现了,对查找这个接口定义两个实现,一个是初始化好数据,另一个是从本地读取。

package com.akwolf.spring.impl;

import java.util.ArrayList;
import java.util.List;

import com.akwolf.bean.Book;
import com.akwolf.spring.BookFinder;

public class CommonBookFinderImpl implements BookFinder {

	@Override
	public List<Book> findAll() {
		List<Book> list = new ArrayList<Book>() ;
		for (int i = 0; i < 20; i++) {
			list.add(new Book("book"+i, "author"+i)) ;
		}
		return list;
	}

}


package com.akwolf.spring.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import com.akwolf.bean.Book;
import com.akwolf.spring.BookFinder;

public class FileBookFinderImpl implements BookFinder {

	@Override
	public List<Book> findAll() {
		List<Book> list = new ArrayList<Book>() ;
		InputStream inputStream;
		try {
			// 从本地数据文件中读取
			inputStream = new FileInputStream(new File("C:" + File.separator
					+ "book.txt"));
			BufferedReader bufferedReader = new BufferedReader(
					new InputStreamReader(inputStream));
			String line = "";
			while ((line = bufferedReader.readLine()) != null) {
				String[] str = line.split(",") ;
				list.add(new Book(str[0], str[1])) ;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return list;
	}
}


book.txt

book1,zhangsan1
book2,zhangsan2
book3,zhangsan3
book4,zhangsan4
book5,zhangsan5
book6,zhangsan6
book7,zhangsan7
book8,zhangsan8


ok、对于BookLister.java这个接口提供使用ArrayList对其实现的类。

package com.akwolf.spring.impl;

import java.util.ArrayList;
import java.util.List;

import com.akwolf.bean.Book;
import com.akwolf.spring.BookFinder;
import com.akwolf.spring.BookLister;

public class BookListerImpl implements BookLister {
	private BookFinder finder ;
	

	public BookListerImpl() {
		// 传统手动实例
		this.finder = new CommonBookFinderImpl() ;
	}
	
	@Override
	public List<Book> findBook(String name) {
		List<Book> books = finder.findAll() ;
		List<Book> findBooks = new ArrayList<Book>() ;
		for (Book book : books) {
			if(book.getName().equals(name)){
				findBooks.add(book) ;
			}
		}
		return findBooks;
	}
}


测试一下

@Test
	public void testLister(){
		BookLister lister = (BookLister) context.getBean("bookLister") ;
		
		System.out.println(lister.findBook("book3"));
	}


好了,,这样程序就可以运行了,,但看看上面的BookListerImpl这个的构造方面还是与另外一个类耦合,需要不同的实现时,还是得修改代码。好吧,那就更进一步,把数据的设置搬到beans.xml中进行配置,咳咳,这就是大名鼎鼎的依赖注入了,注入分两种方法进行注入

i、属性setter方法进行注入,贴上代码

public class BookListerImpl implements BookLister {
	private BookFinder finder ;
	
	public void setFinder(BookFinder finder) {
		// spring 属性注入
		this.finder = finder;
	}
	
	//......
}


beans.xml中也进行一下修改。

<bean
		id="bookLister"
		class="com.akwolf.spring.impl.BookListerImpl">
		<!-- name="finder"属性为BookListerImpl类中的属性 ,将commonBookFinder注入给这个属性 -->
		<property name="finder" ref="commonBookFinder" />
	</bean>


ii、使用构造方法的方式进行注入。

public class BookListerImpl implements BookLister {
	private BookFinder finder ;
	
	public BookListerImpl(BookFinder finder){
		// spring构造器进行注入
		this.finder = finder ;
	}
	
	// ....
}


<bean
		id="bookLister"
		class="com.akwolf.spring.impl.BookListerImpl">
		<!-- 构造器注入 -->
		<constructor-arg>
			<!-- 
			<ref bean="commonBookFinder" /> -->
			<ref bean="fileBookFinder" />
		</constructor-arg>
	</bean>


哈哈,,这样就会好多了,,将解耦的层次更进一步了,,要改变不同的实现,只要在beans.xml中进行修改一下就ok。

四、对集合在beans.xml进行初始化的方法

<!-- 集合属性初始注入值 -->
	<bean
		id="collectionBean"
		class="com.akwolf.bean.CollectionBean">
		<property name="list">
			<list>
				<value>1</value>
				<value>2</value>
				<value>3</value>
				<value>4</value>
			</list>
		</property>
		<property name="set">
			<set>
				<value>6</value>
				<value>5</value>
				<value>4</value>
				<value>3</value>
			</set>
		</property>
		<property name="map">
			<map>
				<entry key="1">
					<value>akwolf</value>
				</entry>
				<entry key="2">
					<value>zhanghua</value>
				</entry>
			</map>
		</property>
		<property name="properties">
			<props>
				<prop key="1">akwolf</prop>
				<prop key="2">zhanghua</prop>
			</props>
		</property>
	</bean>


进行属性设置的java文件

package com.akwolf.bean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class CollectionBean {
	private Set<String> set = new HashSet<String>();
	private List<String> list = new ArrayList<String>();
	private Properties properties = new Properties();
	private Map<String, String> map = new HashMap<String, String>();

	// ----------------------
	// setter & getter
	// ----------------------	
}


好了,这就是小弟对于spring入门的一点理解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: