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

【spring mvc (三)】spring 容器

2016-01-28 16:37 495 查看
1.spring容器的作用:

spring容器本质是一个上下文,是我们编写的应用的环境。为什么要使用这个上下文?传统上我们写a调用b的f方法肯定是在a类的方法中new一个b的对象,在用b的f方法,这样写的问题主要是增加了a,b的耦合,具体体现在,a本来是调用b的方法,但是它必须事先new一个b,new一个b意味着要得知b的另一个接口(本来只要知道f),现在又要知道b的创建接口(构造方法),潜在的问题是如果b的构造接口发生改变,那么会影响到a的代码。比如原来是构造方法,现在改成了工厂方法。

那么如何改进呢?我们不让a来new一个b,而是为这个调用的情景创建一个上下文,在上下文中完成调用。那么就会成为下面的:

class c{

function f(){
    A a = new A();
    B b = new B();
    a.setB(b);
    a.ff();
}
}
这不是标准的java代码。上下文便是C类,c类负责创建实例,并且组装,把b的实例给了a,这样a只管用b就行,不用在担心b的创建了。最终把耦合性带到了C类中。

当然,不足之处在于上下文C还得由我们在掌控。Spring容器所做的工作与C类相同,只不过它要复杂的多,它便是为我们的应用创建了一个不用我们维护的上下文(当然能需要初始化容器内的实例了,其它的是衣来伸手饭来张口。有要用的就拿),在容器内部缓存了很多的实例,我们要用那个,只需要调用这个实例的方法即可,并不用关心创建过程。

2.加载:

在web。xml文件中,通过、

<listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>
listener来初始化容器,ContextLoaderListener是一个类,创建spring容器,这个过程挺复杂,《spring技术内幕》一书讲的很详细。

3.bean:

默认的spring容器配置文件是applicationContext.xml,实际上是定义了容器内要存储的对象。

每一个对象都用bean标签定义。

<?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-3.0.xsd"     xmlns:p="http://www.springframework.org/schema/p">
    <!-- 定义一个bean -->
    <bean id="bean1" class="com.model.Person">
    <!-- 为bean注入属性或者依赖 -->
        <!-- 如果是基本类型,用value标签 -->
        <property name="age"><value>12</value></property>
        <property name="name"><value>liyao</value></property>
        <!-- 如果是引用类型,用ref标签 -->
        <property name="address"><ref bean="bean2"></ref></property>
    </bean>
    
    <bean id="bean2" class="com.model.Address">
    <!-- 为bean注入属性或者依赖 -->
        <property name="address"><value>白云小区</value></property>
    </bean>
    
    <!-- 使用p命名空间 -->
    <bean id="bean3" class="com.model.Address"
         p:address="狄村"/>
    
    <!-- bean scope -->
    <bean id="bean4" class="com.model.Car" scope="prototype"> 
    </bean>
     <bean id="bean5" class="com.model.Car"> 
    </bean>
</beans>
这便是一个例子。

最上面的xmlns声明一个xml文档的命名空间,比如要用p:xxx就要提前声明p命名空间,mvc:也同理。xsi命名空间是指定了其他命名空间的文档。

*每一个bean的id必须唯一,作为标识;

*注入bean的属性时,可以用property标签定义,这是set注入方式,比较推荐着一种。也可以引入p标签,定义起来更方便,需要命名空间。

*bean有一个scope如果是prototype,每次都会new一个新的,如果是单例的,就返回相同的对象,默认单例。

以上是使用xml方式配置bean。

更方便的是使用注解方式,需要在spring-mvc配置文件中加入扫描包的启动注解的配置。

可以用@Component来定一个一个bean。为了更好的理解有@Service@Controller@Resource三个标签,分别标识service层组件,controller组件和dao组件。

如果要使用一个bean,那么可以在声明的上方用@Autowired,返回spring容器中唯一的这个类型的实例,如果有多个,必须再加:

@Autowired
	@Qualifier("dao")
只用一个都不行。

使用注解的方式更加方便,加快开发进度,但是可能可读性不如xml方式。

package com.test;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.beans.BigCar;
import com.model.Address;
import com.model.Car;
import com.model.Person;

@Controller
public class TestController {

	@Qualifier("bean5")
	private Car car;
	@Autowired
	BigCar gc;
	@RequestMapping(value="/index")
	public String index(HttpServletRequest request){
		ServletContext servletContext = request.getServletContext();
		String path = servletContext.getRealPath("/WEB-INF/config/");
		System.out.println(path);
		ApplicationContext a = new FileSystemXmlApplicationContext(path+"/spring.xml");
		Address address = (Address) a.getBean("bean2");
		System.out.println(address.getAddress());
		
		Person person = (Person) a.getBean("bean1");
		System.out.println(person.getAge());
		System.out.println(person.getName());
		
		Address address2 = (Address) a.getBean("bean3");
		System.out.println(address2.getAddress());
		
		Car car1 = (Car) a.getBean("bean4");
		System.out.println(car1.getCount());
		
		Car car2 = (Car) a.getBean("bean5");
		System.out.println(car2.getCount());
		
		//BigCar gc = (BigCar) a.getBean("bean6");
		//System.out.println(gc.getPerson().getAddress());
		gc.getClass();
		System.out.println(gc.getDao());
		System.out.println(gc.getAddress());
		return "index";
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: