Spring 积累

来源:互联网 发布:珠峰node不加密百度云 编辑:程序博客网 时间:2024/06/08 08:40

三种实例化bean的方式

 

1.使用类构造器实例化

<bean id=“orderService" class="cn.itcast.OrderServiceBean"/>

2.使用静态工厂方法实例化

<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>

public class OrderFactory {

public static OrderServiceBean createOrder(){

return new OrderServiceBean();

}

}

3.使用实例工厂方法实例化:

<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>

<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>

public class OrderFactory {

public OrderServiceBean createOrder(){

return new OrderServiceBean();

}

}

 

注:使用静态工厂方法实例化和使用实例工厂方法实例化来创建的bean的作用域是工厂来控制?照样是由xml中的scope属性来控制的!!

Bean的作用域
1、singleton作用域 
当一个bean的作用域设置为singleton,那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,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 id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 
或者
<bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/> 

2、prototype 
prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例(在从容器获取bean时初始化!!),相当于一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个 prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。) 
配置实例: 
<bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/> 
或者 
<beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/> 

3、request 
request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,配置实例: 
request、session、global session使用的时候,首先要在初始化web的web.xml中做如下配置: 
如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可: 
<web-app>
...
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app> 

如果是Servlet2.4以前的web容器,那么你要使用一个javax.servlet.Filter的实现: 
<web-app>
...
<filter> 
<filter-name>requestContextFilter</filter-name> 
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app> 

接着既可以配置bean的作用域了: 
<bean id="role" class="spring.chapter2.maryGame.Role" scope="request"/> 

4、session 
session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效,配置实例: 
配置实例: 
和request配置实例的前提一样,配置好web启动文件就可以如下配置: 
<bean id="role" class="spring.chapter2.maryGame.Role" scope="session"/> 

5、global session 
global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么,web会自动当成session类型来使用。 
配置实例: 
和request配置实例的前提一样,配置好web启动文件就可以如下配置: 
<bean id="role" class="spring.chapter2.maryGame.Role" scope="global session"/>

 

依赖注入

 

依赖注入--手工装配

手工装配依赖对象,在这种方式中又有两种编程方式

1. 在xml配置文件中,通过在bean节点下配置,如

<bean id="orderService" class="cn.itcast.service.OrderServiceBean">

<constructor-arg index=“0” type=“java.lang.String” value=“xxx”/>//构造器注入

<property name=“name” value=“zhao/>//属性setter方法注入

</bean>

2. 在java代码中使用@Autowired或@Resource注解方式进行装配。但我们需要在xml配置文件中配置以下信息:

<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-2.5.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

          <context:annotation-config/>

</beans>

这个配置隐式注册了多个对注释进行解析处理的处理器:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor

注: @Resource注解在spring安装目录的lib\j2ee\common-annotations.jar

 

在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。

    @Autowired 

    private PersonDao  personDao;//用于字段上

    @Autowired

    public void setOrderDao(OrderDao orderDao) {//用于属性的setter方法上

        this.orderDao = orderDao;

    }

@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:

    @Autowired  @Qualifier("personDaoBean")

    private PersonDao  personDao;

 

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

    @Resource(name=“personDaoBean”)

    private PersonDao  personDao;//用于字段上

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

建议使用@Resource,因为@Resource注解属于JAVAEE,@Autowired注解属于Spring

 

依赖注入--自动装配依赖对象

对于自动装配,大家了解一下就可以了,实在不推荐大家使用。例子:

<bean id="..." class="..." autowire="byType"/>

autowire属性取值如下:

byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。

byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。

constructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。

autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。

 

 

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

前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:

<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-2.5.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

          <context:component-scan base-package="cn.zyj"/>

</beans>

其中base-package为需要扫描的包(含子包)

@Service用于标注业务层组件、 @Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

注:

1.@PostConstruct写在方法上,相当于<bean id=“xxx” class=“cn.zyj.OrderServiceBean” init-method=“init” destroy-method=“close”/>当中的init-method属性。此注解属于EJB

@PreDestroy写在方法上,相当于<bean id=“xxx” class=“cn.zyj.OrderServiceBean” init-method=“init” destroy-method=“close”/>当中的destroy-method属性。此注解属于EJB

2.写了<context:component-scan base-package=“cn.zyj”/>便签就不需要<context:annotation-config/>标签了

3.Bean的作用域用@Scope注解写在类上。例如@Scope(“prototype”)

 

spring中的BeanFactory与ApplicationContext的作用有哪些? 

1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。 
2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能: 
a. 国际化支持 
b. 资源访问:Resource rs = ctx. getResource(”classpath:config.properties”), “file:c:/config.properties” 
c. 事件传递:通过实现ApplicationContextAware接口 
3. 常用的获取ApplicationContext的方法: 
FileSystemXmlApplicationContext:从文件系统或者url指定的xml配置文件创建,参数为配置文件名或文件名数组 
ClassPathXmlApplicationContext:从classpath的xml配置文件创建,可以从jar包中读取配置文件 
WebApplicationContextUtils:从web应用的根目录读取配置文件,需要先在web.xml中配置,可以配置监听器或者servlet来实现 
<listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<servlet> 
<servlet-name>context</servlet-name> 
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> 
<load-on-startup>1</load-on-startup> 
</servlet> 
这两种方式都默认配置文件为web-inf/applicationContext.xml,也可使用context-param指定配置文件 
<context-param> 
<param-name>contextConfigLocation</param-name> 
<param-value>/WEB-INF/myApplicationContext.xml</param-value> 
</context-param> 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击