不明觉厉的spring(2)---spring核心容器及ioc

spring版本:3.1.0

spring包的各个作用

org.springframework.aop-3.1.1.RELEASE.jar ---- ----spring 的面向切面编程,提供AOP(面向切面编程)实现,

org.springframework.asm-3.1.1.RELEASE.jar ---- ---- Spring独立的asm程序, Spring2.5.6的时候需要asmJar 包,3.0开始提供他自己独立的asm.jar 

。ASM是小巧轻便的 Java 字节码操控框架 ,它能方便地生成和改造 Java 代码。 Hibernate 和 Spring 在底层都用到了 ASM(CgLib 底层用的 asm)。
管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。
件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。
服务、任务调度、JNDI定位、EJB 集成、远程访问、 缓存以及各种视图层框架的封装等。
件的基本核心。
已经独立成包了,现在不包含在这个包里了。这个jar文件里大部分的类都要依赖spring-dao.jar里的类,用这个包时你需要同时包含spring-dao.jar包 

特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。

org.springframework.aspects-3.1.1.RELEASE.jar ---- ---- spring整合了aspectjrt.jar,也可以使用aspectjrt.jar来代替。

org.springframework.beans-3.1.1.RELEASE.jar ---- ---- springIoC(依赖注入)的基础实现,所有应用都要用到的,它包含访问配置文件、创建和 

org.springframework.context.support-3.1.1.RELEASE.jar ---- ---- spring-context 的扩展支持,包含支持缓存Cache(ehcache)、JCA、JMX、邮 

org.springframework.context-3.1.1.RELEASE.jar ---- ----spring 提供在基础 IoC 功能上的扩展服务,此外还提供许多企业级服务的支持,如 邮件 

org.springframework.core-3.1.1.RELEASE.jar ---- ---- 包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组 

org.springframework.expression-3.1.1.RELEASE.jar ---- ----spring 表达式语言。

org.springframework.instrument.tomcat-3.1.1.RELEASE.jar ---- ----spring3.1 对 Tomcat 的连接池的基成。

org.springframework.instrument-3.1.1.RELEASE.jar ---- ----spring3.1 对服务器的代理接口。

org.springframework.jdbc-3.1.1.RELEASE.jar ---- ----包含对Spring对JDBC数据访问进行封装的所有类。

org.springframework.jms-3.1.1.RELEASE.jar ---- ----提供了对JMS 1.0.2/1.1的支持类。

org.springframework.orm-3.1.1.RELEASE.jar ---- ----包含Spring对DAO特性集进行了扩展,使其支持 iBATIS、JDO、OJB、TopLink,因为Hibernate 

org.springframework.oxm-3.1.1.RELEASE.jar ---- ----spring 对Object/XMI 的映射的支持,可以让JAVA与XML之间来回切换。

org.springframework.test-3.1.1.RELEASE.jar ---- ----spring 对Junit 等测试框架的简单封装。

org.springframework.transaction-3.1.1.RELEASE.jar ---- ----为为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。

org.springframework.web.portlet-3.1.1.RELEASE.jar ---- ----springMVC 的增强,支持portlet标准(JSR168/JSR286)。

org.springframework.web.servlet-3.1.1.RELEASE.jar ---- ----对 J2EE6.0 Servlet3.0 的支持。

org.springframework.web.struts-3.1.1.RELEASE.jar ---- ---- 整合 Struts 的支持。

org.springframework.web-3.1.1.RELEASE.jar ---- ----包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext 

spring容器的实例化方式

方法一:
在类路径下寻找配置文件来实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
方法二:
在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多个,可以通过String数组传入。

bean的实例化方法

使用构造器创建实例

无参构造函数

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<bean id="classA" class="spring.senssic.A">
	</bean>
</beans>
public A(){}

有参构造函数

package spring.senssic.temp;
import java.util.Date;
public class B {
	private final String name;
	private final int age;
	private final Date date;
	public B(String name, int age, Date date) {
		this.name = name;
		this.age = age;
		this.date = date;
	}
	@Override
	public String toString() {
		return "实例化成功:name" + this.name + "age:" + this.age + date;
	}
}


<?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"
       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-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="date" class="java.util.Date"></bean>
<bean id="classb" class="spring.senssic.temp.B">
   <constructor-arg index="0" value="senssic"></constructor-arg>
   <constructor-arg index="1" value="20"></constructor-arg>
   <constructor-arg index="2" ref="date"></constructor-arg>
</bean>
</beans>
测试类:
package spring.senssic.test;

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import spring.senssic.temp.B;

public class STest {
	private static B b;

	@BeforeClass
	public static void TWork() {
		ApplicationContext act = new ClassPathXmlApplicationContext("beans.xml");
		b = (B) act.getBean("classb");

	}

	@Test
	public void test() {
		System.out.println(b.toString());
	}
}


使用静态工厂方法创建实例

package spring.senssic.temp;
public class C {
public static C createInstance() {// 必须是无参静态
return new C();
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "无参静态函数";
}
}


bean:
<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean>

使用实例工厂方法创建实例

工厂类

package spring.senssic.temp;

import java.util.Date;

public class Factory {
	private final String name = "senssic";

	public B Instance() {// 必须是无参函数,且是public类型
		return new B(name, 20, new Date());
	}
}

要实例化的类:
package spring.senssic.temp;

import java.util.Date;

public class B {
	private final String name;
	private final int age;
	private final Date date;

	public B(String name, int age, Date date) {
		this.name = name;
		this.age = age;
		this.date = date;
	}

	@Override
	public String toString() {

		return "实例化成功:name" + this.name + "age:" + this.age + date;
	}
}

配置:

<bean id="factory" class="spring.senssic.temp.Factory"></bean>
<bean id="classb" factory-bean="factory" factory-method="Instance"></bean><!--就是通过factory类来反射实例化B-->

bean的作用域

Spring Framework支持五种作用域(其中有三种只能用在基于web的Spring ApplicationContext)。 
内置支持的作用域分列如下:
作用域                                    描述


singleton---默认为此项
在每个Spring IoC容器中一个bean定义对应一个对象实例。

当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。

设置的方式

<bean id="accountService" class="spring.senssic.temp.AccountSer"/> 

<bean id="accountService" class="spring.senssic.temp.AccountSer" scope="singleton"/>  

<bean id="accountService" class="spring.senssic.temp.AccountSer" singleton="true"/> 


prototype
一个bean定义对应多个对象实例。

Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean() 方法)时都会创建一个新的bean实例 。根据经验,对有状态的bean应该使用singleton作用域,而对无状态的bean则应该使用prototype作用域。

设置方式:

<bean id="accountService" class="spring.senssic.temp.AccountSer" scope="prototype"/>  

<bean id="personService" class="spring.senssic.temp.AccountSer" scope="prototype"></bean> 


request

在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext 情形下有效。
session
在一个HTTP Session 中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext 情形下有效。
global session
在一个全局的HTTP Session 中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext 情形下有效。

其他作用域,即request、session以及global session 仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架)。这些作用域仅仅在使用基于web的Spring ApplicationContext实现(如XmlWebApplicationContext)时有用。 如果在普通的Spring IoC容器中,比如像XmlBeanFactory或ClassPathXmlApplicationContext, 尝试使用这些作用域,你将会得到一个IllegalStateException异常(未知的bean作用域)。配置只需要改下scope属性即可

bean的懒加载

在每个Spring IoC容器中一个bean定义只有一个对象实例。默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
 <bean id="xxx" class="cn.itcast.OrderServiceBean" lazy-init="true"/>
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:
<beans default-lazy-init="true“ ...>


指定Bean的初始化方法和销毁方法

指定Bean的初始化方法和销毁方法
<bean id="xxx" class="cn.itcast.OrderServiceBean" init-method="init" destroy-method="close"/>

依赖注入

spring依赖注入
使用构造器注入
使用属性setter方法注入
使用Field注入(用于注解方式)

构造函数的注入之前已经介绍

不使用注解方式

使用setter方法注入:

基本类型

java代码:属性必须有setter方法,必须有无参构造函数
package spring.senssic.temp;


public class B {
	private String name;


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


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


	private int age;


	public B() {
	}


	public B(String name, int age) {
		this.name = name;
		this.age = age;


	}


	@Override
	public String toString() {


		return "实例化成功:name" + this.name + "age:" + this.age;
	}


	public String getName() {
		return name;
	}


	public int getAge() {
		return age;
	}
}

配置:
<bean id="classb" class="spring.senssic.temp.B">
 <property name="name" value="senssic"></property>
 <property name="age" value="20"></property>
</bean>

引用其它bean

其他定义class

package spring.senssic.temp;
public class C {
public static C createInstance() {// 必须是无参静态
return new C();
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "无参静态函数";
}
}
需要配置的:

package spring.senssic.temp;

public class B {
	private String name;
	private C c;

	public C getC() {
		return c;
	}

	public void setC(C c) {
		this.c = c;
	}

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

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

	private int age;

	public B() {
	}

	public B(String name, int age) {
		this.name = name;
		this.age = age;

	}

	@Override
	public String toString() {

		return "实例化成功:name" + this.name + "age:" + this.age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
}
配置文件:

<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean>
<bean id="classb" class="spring.senssic.temp.B">
 <property name="name" value="senssic"></property>
 <property name="age" value="20"></property>
 <property name="c" ref="classc"></property>
</bean>

内部bean(使用内部bean,但该bean不能被其他bean使用)

引用类:
package spring.senssic.temp;

class D {

}
java类:
package spring.senssic.temp;

public class B {
	public D getD() {
		return d;
	}

	public void setD(D d) {
		this.d = d;
	}

	private D d;

	@Override
	public String toString() {
		return "lalalal";
	}

}

配置文件:
<bean id="classb" class="spring.senssic.temp.B">
 <property name="d">
   <bean class="spring.senssic.temp.D"></bean>
 </property>

这种方式的缺点是你无法在其它地方重用这个D实例,原因是它是专门为B而用。

装配集合

若bean的属性是集合类型,按如下处理:
A、装配List和数组:
                <!-- 装配list -->
                  <propertyname="lists">
                       <list>
                        <value>list1</value>
                        <value>list2</value>
                        <refbean="person"/>
                     </list>
                   </property>
   <!--装配数组 -->
       <property name="obj">
         <list>
            <value>obj1</value>
            <value>obj2</value>
            <refbean="person"/>
         </list>
       </property>
B、 装配set:
  <!--装配set -->
       <property name="sets">
         <set>
           <value>set1</value>
           <value>set2</value>
           <refbean="person"/>
         </set>
       </property>
set使用方法和list一样,不同的是对象被装配到set中,而list是装配到List或数组中装配。   
C、装配map:
     <!-- 装配map-->
      <propertyname="maps">
               <map>
                 <entrykey="01">
                   <value>map01</value>
                  </entry>
                  <entrykey="02">
                      <value>map02</value>
                   </entry>
                 </map>
       </property>
   map中的<entry>的数值和<list>以及<set>的一样,可以使任何有效的属性元素,需要注意的是key值必须是String的。
D、装配Properties:
    <!--装配Properties  -->
      <property name="props">
         <props>
           <prop key="01">prop1</prop>
           <prop key="02">prop2</prop>
         </props>
      </property>
E、设置null:
     <!--装配null -->
     <property name="listnull">
        <null/>
     </property>

通过构造方法传递参数:不需要写settter方法也可实例化

   通过参数的顺序:
         <constructor-argindex="0">
            <value>张三</value>
         </constructor-arg>
         <constructor-argindex="1">
             <value>56</value>
          </constructor-arg>
   通过构造函数注入依赖
         <!--通过参数的类型 -->
      <constructor-argtype="java.lang.Integer">
          <value>56</value>
      </constructor-arg>
      <constructor-argtype="java.lang.String">
          <value>张三</value>
       </constructor-arg>


手动注解装配

注解就是spring可以自动帮你把bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get。

如果想使用注解装配需要在配置文件中增加如下信息:
<context:annotation-config/>
即完整的为:
<?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"
       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-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:annotation-config></context:annotation-config><!--启动注解装配-->
</beans>
在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired  @Qualifier("personDaoBean")
  private PersonDao  personDao;
eg:
java代码:
package spring.senssic.temp;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class B {
	@Autowired
	private C c;
	@Autowired(required = false)
	// 如果不写false需要写setter方法并在文件中配置property
	private int age;
	@Autowired
	@Qualifier(value = "date")
	private Date d;

	@Override
	public String toString() {
		return "--->" + this.age + d;
	}
}

配置:
<?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"
       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-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:annotation-config></context:annotation-config>
<bean id="date" class="java.util.Date"></bean>
<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean>
<bean id="classb" class="spring.senssic.temp.B">
</bean>
</beans>

当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中


@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
java代码:
package spring.senssic.temp;

import javax.annotation.Resource;

public class D {
	@Resource(name = "classc")
	private C c;

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "lalalal";
	}

}

配置文件:
<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean>
<bean id="classd" class="spring.senssic.temp.D"></bean>

注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。

自动装配

对于自动装配,大家了解一下就可以了,实在不推荐大家使用。例子:
<bean id="..." class="..." autowire="byType"/>
autowire属性取值如下:
byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。
constructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。

通过在classpath自动扫描方式把组件纳入spring容器中管理

spring2.5后为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。
要使用自动扫描机制,我们需要打开以下配置信息:
 1、引入context命名空间 需要在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:context="http://www.springframework.org/schema/context"
       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-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:component-scan base-package="spring.senssic"></context:component-scan>
 2、在配置文件中添加context:component-scan标签
     <context:component-scanbase-package="spring.senssic"/>
     其中base-package为需要扫描的包(含子包)。
     注:
     1、在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。
     2、功能介绍
        @Service用于标注业务层组件、
        @Controller用于标注控制层组件(如struts中的action)、
        @Repository用于标注数据访问组件,即DAO组件。
        而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
eg:
                                   //Dao层
importorg.springframework.stereotype.Repository;
importcom.test.dao.PersonDao;


@Repository("personDao")
 publicclassPersonDaoBean implements PersonDao {
}
//业务层
importjavax.annotation.Resource;
importorg.springframework.stereotype.Service;
importcom.test.dao.PersonDao;
importcom.test.service.PersonService;


@Service("personService")
publicclassPersonServiceBean implements PersonService {
@Resource(name="personDao")
privatePersonDao personDao;
 }



注入方式:   
把DAO实现类注入到service实现类中,把service的接口(注意不要是service的实现类)注入到action中,注   
入时不要new 这个注入的类,因为spring会自动注入,如果手动再new的话会出现错误.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值