spring中bean配置和bean注入
1 bean与spring容器的关系
Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。
1 bean配置
bean配置有三种方法:
- 基于xml配置Bean
- 使用注解定义Bean
- 基于java类提供Bean定义信息
1.1 基于xml配置Bean
对于基于XML的配置,Spring 2.0以后使用Schema的格式,使得不同类型的配置拥有了自己的命名空间,是配置文件更具扩展性。
①默认命名空间:它没有空间名,用于Spring Bean的定义;
②xsi命名空间:这个命名空间用于为每个文档中命名空间指定相应的Schema样式文件,是标准组织定义的标准命名空间;
③aop命名空间:这个命名空间是Spring配置AOP的命名空间,是用户自定义的命名空间。
命名空间的定义分为两个步骤:第一步指定命名空间的名称;第二步指定命名空间的Schema文档样式文件的位置,用空格或回车换行进行分分隔。
1.1.1 Bean基本配置
在Spring容器的配置文件中定义一个简要Bean的配置片段如下所示:
一般情况下,Spring IOC容器中的一个Bean即对应配置文件中的一个<bean>,这种镜像对应关系应该容易理解。其中id为这个Bean的名称,通过容器的getBean("foo")即可获取对应的Bean,在容器中起到定位查找的作用,是外部程序和Spring IOC容器进行交互的桥梁。class属性指定了Bean对应的实现类。
下面是基于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">
<bean id="car" name="#car1" class="com.baobaotao.simple.Car"></bean>
<bean id="boss" class="com.baobaotao.simple.Boss"></bean>
</beans>
1.1.2 依赖注入
- 属性注入
- 构造函数注入
- 工厂方式注入
1.2 使用注解定义Bean
我们知道,Spring容器成功启动的三大要件分别是:Bean定义信息、Bean实现类以及Spring本身。如果采用基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。
下面是使用注解定义一个DAO的Bean:
package com.baobaotao.anno; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
//①通过Repository定义一个DAO的Bean @Component("userDao")
public class UserDao { }
在①处,我们使用@Component注解在UserDao类声明处对类进行标注,它可以被Spring容器识别,Spring容器自动将POJO转换为容器管理的Bean。
它和以下的XML配置是等效的:
<bean id="userDao" class="com.baobaotao.anno.UserDao"/>
除了@Component以外,Spring提供了3个功能基本和@Component等效的注解,它们分别用于对DAO、Service及Web层的Controller进行注解,所以也称这些注解为Bean的衍型注解:(类似于xml文件中定义Bean<bean id=" " class=" "/>
- @Repository:用于对DAO实现类进行标注;
- @Service:用于对Service实现类进行标注;
- @Controller:用于对Controller实现类进行标注;
之所以要在@Component之外提供这三个特殊的注解,是为了让注解类本身的用途清晰化,此外Spring将赋予它们一些特殊的功能。
1.2.1 使用注解配置信息启动spring容器
Spring提供了一个context的命名空间,它提供了通过扫描类包以应用注解定义Bean的方式:
<?xml version="1.0" encoding="UTF-8" ?>
<!--①声明context的命名空间-->
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<!--②扫描类包以应用注解定义的Bean-->
<context:component-scan base-package="com.baobaotao.anno"/>
<bean class="com.baobaotao.anno.LogonService"></bean>
<!-- context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ -->
<!-- context:component-scan base-package="com.baobaotao">
<context:include-filter type="regex" expression="com\.baobaotao\.anno.*Dao"/>
<context:include-filter type="regex" expression="com\.baobaotao\.anno.*Service"/>
<context:exclude-filter type="aspectj" expression="com.baobaotao..*Controller+"/>
</context:component-scan -->
</beans>
在①处声明context命名空间,在②处即可通过context命名空间的component-scan的base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里的所有类,并从类的注解信息中获取Bean的定义信息。
如果仅希望扫描特定的类而非基包下的所有类,你们可以使用resource-pattern属性过滤特定的类,如下所示:
< context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ >
这里我们将基类包设置为com.baobaotao,默认情况下resource-pattern属性的值为"**/*.class",即基类包里的所有类。这里我们设置为"anno/*.class",则Spring仅会扫描基包里anno子包中的类。
1.3 基于java类提供Bean定义
在普通的POJO类中只要标注@Configuration注解,就可以为spring容器提供Bean定义的信息了,每个标注了@Bean的类方法都相当于提供了一个Bean的定义信息。
package com.baobaotao.conf; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//①将一个POJO标注为定义Bean的配置类
@Configuration
public class AppConf {
//②以下两个方法定义了两个Bean,以提供了Bean的实例化逻辑
@Bean
public UserDao userDao(){
return new UserDao();
} @Bean
public LogDao logDao(){
return new LogDao();
}
//③定义了logonService的Bean
@Bean
public LogonService logonService(){
LogonService logonService = new LogonService();
//④将②和③处定义的Bean注入到LogonService Bean中
logonService.setLogDao(logDao());
logonService.setUserDao(userDao());
return logonService;
}
}
①处在APPConf类的定义处标注了@Configuration注解,说明这个类可用于为Spring提供Bean的定义信息。类的方法处可以标注@Bean注解,Bean的类型由方法返回值类型决定,名称默认和方法名相同,也可以通过入参显示指定Bean名称,如@Bean(name="userDao").直接在@Bean所标注的方法中提供Bean的实例化逻辑。
在②处userDao()和logDao()方法定义了一个UserDao和一个LogDao的Bean,它们的Bean名称分别是userDao和logDao。在③处,又定义了一个logonService Bean,并且在④处注入②处所定义的两个Bean。
因此,以上的配置和以下XML配置时等效的:
<bean id="userDao" class="com.baobaotao.anno.UserDao"/>
<bean id="logDao" class="com.baobaotao.anno.LogDao"/>
<bean id="logService" class="com.baobaotao.conf.LogonService"
p:logDao-ref="logDao" p:userDao-ref="userDao"/>
基于java类的配置方式和基于XML或基于注解的配置方式相比,前者通过代码的方式更加灵活地实现了Bean的实例化及Bean之间的装配,但后面两者都是通过配置声明的方式,在灵活性上要稍逊一些,但是配置上要更简单一些。
2 Bean注入
Bean注入的方式有两种,一种是在XML中配置,此时分别有属性注入、构造函数注入和工厂方法注入;另一种则是使用注解的方式注入@Autowired,@Resource,@Required。
2.1 在xml文件中配置依赖注入
2.1.1 属性注入
属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。
属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。
package com.baobaotao.anno; import org.springframework.beans.factory.BeanNameAware; public class LogonService implements BeanNameAware{ private LogDao logDao; private UserDao userDao; public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public void setLogDao(LogDao logDao) {
this.logDao = logDao;
} public LogDao getLogDao() {
return logDao;
}
public UserDao getUserDao() {
return userDao;
} public void setBeanName(String beanName) {
System.out.println("beanName:"+beanName);
} public void initMethod1(){
System.out.println("initMethod1");
}
public void initMethod2(){
System.out.println("initMethod2");
} }
bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
default-autowire="byName"
>
<bean id="logDao" class="com.baobaotao.anno.LogDao"/>
<bean id="userDao" class="com.baobaotao.anno.UserDao"/>
<bean class="com.baobaotao.anno.LogonService">
<property name="logDao" ref="logDao"></property>
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
2.1.2 构造方法注入
使用构造函数注入的前提是Bean必须提供带参数的构造函数。例如
package com.baobaotao.anno; import org.springframework.beans.factory.BeanNameAware; public class LogonService implements BeanNameAware{ public LogonService(){} public LogonService(LogDao logDao, UserDao userDao) {
this.logDao = logDao;
this.userDao = userDao;
} private LogDao logDao; private UserDao userDao; public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public void setLogDao(LogDao logDao) {
this.logDao = logDao;
} public LogDao getLogDao() {
return logDao;
}
public UserDao getUserDao() {
return userDao;
} public void setBeanName(String beanName) {
System.out.println("beanName:"+beanName);
} public void initMethod1(){
System.out.println("initMethod1");
}
public void initMethod2(){
System.out.println("initMethod2");
} }
bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
default-autowire="byName"> <bean id="logDao" class="com.baobaotao.anno.LogDao"/>
<bean id="userDao" class="com.baobaotao.anno.UserDao"/>
<bean class="com.baobaotao.anno.LogonService">
<constructor-arg ref="logDao"></constructor-arg>
<constructor-arg ref="userDao"></constructor-arg>
</bean> </beans>
2.1.3 工厂方法注入
非静态工厂方法:
有些工厂方法是非静态的,即必须实例化工厂类后才能调用工厂放。
package com.baobaotao.ditype; public class CarFactory {
public Car createHongQiCar(){
Car car = new Car();
car.setBrand("红旗CA72");
return car;
} public static Car createCar(){
Car car = new Car();
return car;
}
}
工厂类负责创建一个或多个目标类实例,工厂类方法一般以接口或抽象类变量的形式返回目标类实例,工厂类对外屏蔽了目标类的实例化步骤,调用者甚至不用知道具体的目标类是什么。
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 工厂方法-->
<bean id="carFactory" class="com.baobaotao.ditype.CarFactory" />
<bean id="car5" factory-bean="carFactory" factory-method="createHongQiCar">
</bean> </beans>
静态工厂方法:
很多工厂类都是静态的,这意味着用户在无须创建工厂类实例的情况下就可以调用工厂类方法,因此,静态工厂方法比非静态工厂方法的调用更加方便。
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="car6" class="com.baobaotao.ditype.CarFactory"
factory-method="createCar"></bean> </beans>
2.2 使用注解的方式注入
2.2.1 使用@Autowired进行自动注入
Spring通过@Autowired注解实现Bean的依赖注入,下面是一个例子:
package com.baobaotao.anno; import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
//① 定义一个Service的Bean(不需要在XML中定义Bean)
@Service
public class LogonService implements BeanNameAware{
//② 分别注入LogDao及UserDao的Bean(不需要在XML中定义property属性注入)
@Autowired(required=false)
private LogDao logDao;
@Autowired
@Qualifier("userDao")
private UserDao userDao; public LogDao getLogDao() {
return logDao;
}
public UserDao getUserDao() {
return userDao;
} public void setBeanName(String beanName) {
System.out.println("beanName:"+beanName);
} public void initMethod1(){
System.out.println("initMethod1");
}
public void initMethod2(){
System.out.println("initMethod2");
} }
在①处,我们使用@Service将LogonService标注为一个Bean,在②处,通过@Autowired注入LogDao及UserDao的Bean。@Autowired默认按类型匹配的方式,在容器查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入到@Autowired标注的变量中。
2.2.2 使用@Autowired的required属性
如果容器中没有一个和标注变量类型匹配的Bean,Spring容器启动时将报NoSuchBeanDefinitionException的异常。如果希望Spring即使找不到匹配的Bean完成注入也不用抛出异常,那么可以使用@Autowired(required=false)进行标注:
@Service
public class LogonService implements BeanNameAware{
@Autowired(required=false)
private LogDao logDao;
...
}
默认情况下,@Autowired的required属性的值为true,即要求一定要找到匹配的Bean,否则将报异常。
2.2.3 使用@Qualifier指定注入Bean的名称
如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称,如下所示:
@Service
public class LogonService implements BeanNameAware{
@Autowired(required=false)
private LogDao logDao;
//①注入名为UserDao,类型为UserDao的Bean
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
这里假设容器有两个类型为UserDao的Bean,一个名为userDao,另一个名为otherUserDao,则①处会注入名为userDao的Bean。
2.2.4 对类方法进行标注
@Autowired可以对类成员变量及方法的入参进行标注,下面我们在类的方法上使用@Autowired注解:
package com.baobaotao.anno; import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; @Service
public class LogonService implements BeanNameAware{ private LogDao logDao;
private UserDao userDao; @Autowired
public void setLogDao(LogDao logDao) {
this.logDao = logDao;
} @Autowired
@Qualifier("userDao")
public void setUserDao(UserDao userDao) {
System.out.println("auto inject");
this.userDao = userDao;
} }
如果一个方法拥有多个入参,在默认情况下,Spring自动选择匹配入参类型的Bean进行注入。Spring允许对方法入参标注@Qualifier以指定注入Bean的名称,如下所示:
@Autowired
public void init(@Qualifier("userDao")UserDao userDao,LogDao logDao){
System.out.println("multi param inject");
this.userDao = userDao;
this.logDao =logDao;
}
在以上例子中,UserDao的入参注入名为userDao的Bean,而LogDao的入参注入LogDao类型的Bean。
一般情况下,在Spring容器中大部分的Bean都是单实例的,所以我们一般都无须通过@Repository、@Service等注解的value属性为Bean指定名称,也无须使用@Qualifier按名称进行注入。
2.2.5 对标准注解的支持
此外,Spring还支持@Resource和@Inject注解,这两个标准注解和@Autowired注解的功能类型,都是对类变量及方法入参提供自动注入的功能。@Resource要求提供一个Bean名称的属性,如果属性为空,则自动采用标注处的变量名或方法名作为Bean的名称。
package com.baobaotao.anno; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component
public class Boss { private Car car; public Boss(){
System.out.println("construct...");
} // @Autowired
// private void setCar(Car car){
// System.out.println("execute in setCar");
// this.car = car;
// } @Resource("car")
private void setCar(Car car){
System.out.println("execute in setCar");
this.car = car;
} @PostConstruct
private void init1(){
System.out.println("execute in init1");
} @PostConstruct
private void init2(){
System.out.println("execute in init1");
} @PreDestroy
private void destory1(){
System.out.println("execute in destory1");
} @PreDestroy
private void destory2(){
System.out.println("execute in destory2");
} }
这时,如果@Resource未指定"car"属性,则也可以根据属性方法得到需要注入的Bean名称。可见@Autowired默认按类型匹配注入Bean,@Resource则按名称匹配注入Bean。而@Inject和@Autowired一样也是按类型匹配注入的Bean的,只不过它没有required属性。可见不管是@Resource还是@Inject注解,其功能都没有@Autowired丰富,因此除非必须,大可不必在乎这两个注解。(类似于Xml中使用<constructor-arg ref="logDao"></constructor-arg>或者<property name="logDao" ref="logDao"></property>进行注入,如果使用了@Autowired或者Resource等,这不需要在定义Bean时使用属性注入和构造方法注入了)
2.2.6 关于Autowired和@Resource
1.@Autowired注入是按照类型注入的,只要配置文件中的bean类型和需要的bean类型是一致的,这时候注入就没问题。但是如果相同类型的bean不止一个,此时注入就会出现问题,Spring容器无法启动。
2.@Resourced标签是按照bean的名字来进行注入的,如果我们没有在使用@Resource时指定bean的名字,同时Spring容器中又没有该名字的bean,这时候@Resource就会退化为@Autowired即按照类型注入,这样就有可能违背了使用@Resource的初衷。所以建议在使用@Resource时都显示指定一下bean的名字@Resource(name="xxx")
2.2.7 让@Resource和@Autowired生效的几种方式
1.在xml配置文件中显式指定
<!-- 为了使用Autowired标签,我们必须在这里配置一个bean的后置处理器 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> <!-- 为了使用@Resource标签,这里必须配置一个后置处理器 -->
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
2.在xml配置文件中使用context:annotation-config
<context:annotation-config />
3.在xml配置文件中使用context:component-scan
<context:component-scan base-package="com.baobaotao.anno"/>
4.重写Spring容器的Context,在自定义BeanFactory时调用AnnotationConfigUtils.registerAnnotationConfigProcessors()把这两个注解处理器增加到容器中。
一开始使用公司框架的时候发现可以在web层使用@Resource以及@Autowired来注入一些bean,首先这个注解是Spring提供的,自己把这部分代码抽出来写了小例子,发现要想使用Spring的这两注解,必须直接或者间接的引入AutowiredAnnotationBeanPostProcesso以及CommonAnnotationBeanPostProcessor这两个注解处理器引入到BeanDefinitions中,否则不会实现注入的,但是仔细阅读公司框架代码后发现没有地方直接或间接引入这两个注解处理器,发现一个细节,公司框架所依赖的Spring版本是2.5.6而我使用的Spring版本是2.5.5,当初的结论是高版本的Spring在容器启动的时候,自动把这两个注解处理器加入到BeanDefinitions中,这几天仔细看了看Spring的源代码,发现Spring2.5.6并没有这样做。然后子写DEBUG了一下公司框架的源代码,最后发现原来公司框架有一个自己的XmlWebApplicationContext,在这个context中重写customizeBeanFactory(),在这个方法中调用了AnnotationConfigUtils.registerAnnotationConfigProcessors()方法把这两自动注解处理器加入到BeanDefinitions中,这样公司框架在web层就支持@Resource和@Autowired进行自动注入啦
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.alibaba.citrus.springext.support.context; import com.alibaba.citrus.springext.ResourceLoadingExtendable;
import com.alibaba.citrus.springext.ResourceLoadingExtender;
import com.alibaba.citrus.springext.support.context.InheritableListableBeanFactory;
import com.alibaba.citrus.springext.support.resolver.XmlBeanDefinitionReaderProcessor;
import java.io.IOException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver; public class XmlWebApplicationContext extends org.springframework.web.context.support.XmlWebApplicationContext implements ResourceLoadingExtendable {
private ResourceLoadingExtender resourceLoadingExtender;
private boolean parentResolvableDependenciesAccessible = true; public XmlWebApplicationContext() {
} public boolean isParentResolvableDependenciesAccessible() {
return this.parentResolvableDependenciesAccessible;
} public void setParentResolvableDependenciesAccessible(boolean parentResolvableDependenciesAccessible) {
this.parentResolvableDependenciesAccessible = parentResolvableDependenciesAccessible;
} public void setResourceLoadingExtender(ResourceLoadingExtender resourceLoadingExtender) {
if(this.resourceLoadingExtender != null) {
this.getApplicationListeners().remove(this.resourceLoadingExtender);
} this.resourceLoadingExtender = resourceLoadingExtender;
if(resourceLoadingExtender instanceof ApplicationListener) {
this.addApplicationListener((ApplicationListener)resourceLoadingExtender);
} } protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
(new XmlBeanDefinitionReaderProcessor(beanDefinitionReader)).addConfigurationPointsSupport();
} protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
super.customizeBeanFactory(beanFactory);
//AnnotationConfigUtils.registerAnnotationConfigProcessors()方法把这两自动注解处理器加入到BeanDefinitions中,这样公司框架在web层就支持@Resource和@Autowired进行自动注入
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory, (Object)null);
} protected DefaultListableBeanFactory createBeanFactory() {
return (DefaultListableBeanFactory)(this.isParentResolvableDependenciesAccessible()?new InheritableListableBeanFactory(this.getInternalParentBeanFactory()):super.createBeanFactory());
} protected Resource getResourceByPath(String path) {
Resource resource = null;
if(this.resourceLoadingExtender != null) {
resource = this.resourceLoadingExtender.getResourceByPath(path);
} if(resource == null) {
resource = super.getResourceByPath(path);
} return resource;
} protected ResourcePatternResolver getResourcePatternResolver() {
final ResourcePatternResolver defaultResolver = super.getResourcePatternResolver();
return new ResourcePatternResolver() {
public Resource[] getResources(String locationPattern) throws IOException {
ResourcePatternResolver resolver = null;
if(XmlWebApplicationContext.this.resourceLoadingExtender != null) {
resolver = XmlWebApplicationContext.this.resourceLoadingExtender.getResourcePatternResolver();
} if(resolver == null) {
resolver = defaultResolver;
} return resolver.getResources(locationPattern);
} public ClassLoader getClassLoader() {
return defaultResolver.getClassLoader();
} public Resource getResource(String location) {
return defaultResolver.getResource(location);
}
};
}
}
spring中bean配置和bean注入的更多相关文章
- 谈谈Spring中的对象跟Bean,你知道Spring怎么创建对象的吗?
本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 推荐阅读: Spring官网阅读 | 总结篇 Spring杂 ...
- hessian 在spring中的使用 (bean 如 Dao无法注入的问题)
hessian的主要结构分客户端与服务端,中间基于http传输.客户端主要做的事情是把对远程接口调用序列化为流,并传输到服务端:服务端主要做的事情是把传输过来的流反序列化为对服务的请求,调用相应服务后 ...
- Spring中常用类型的bean配置(Map,List,Set,基本类型)
给自己做个笔记... 有时会用到配置文件中配置一下映射关系,方便以后扩展.此时可采用集合类型的bean配置方式配置.程序中直接注入即可. map类型的: <!-- 旧版方式,无需util包 -- ...
- [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- spring中涉及事务(bean中ref与local)
<bean id="接口" parent="父id"> <property name="target"> <r ...
- Spring中继承配置的注入方法
(1)两个java类.一个父类一个字类 package com.lc.inherit; /* * 这里是父类 */ public class Student { protected String na ...
- 在spring中如何生成一个bean (一个对象,比如jedis的连接池对象)【我】
在spring中,要想生成一个单例对象(比如jedis的连接池对象) 方法1: 在 spring中用 bean 标签生成(反正就是让spring生成并管理单例的对象) 方法2: 把要生成的单例对象类, ...
- Spring中applicationContext.xml的bean里的id和name属性区别
转自:http://www.cnblogs.com/ztf2008/archive/2009/02/11/1388003.html <beans><bean id="per ...
- Spring 中属性配置
1 注册自定义属性编辑器,方法一.使用BeanFactory, 则用户需要手动调用 registerCustomEditor(Class requiredType, PropertyEditor pr ...
随机推荐
- BugTracker 加入发Mail的功能
BugTracker部署好之后,发现增加bug不能mail提醒.于是补上这个功能记录在此,方法是次要的,主要是找到地方.需要3步.吐槽下Asp的代码风格看的真心蛋疼.... 一.发送mail(主要是找 ...
- 关于网卡eth0、eth1以及服务器为什么要把内网和外网卡区分开
在搜搜上看到了这个回答,它解释了什么是eth0,eth1: eth0和eth1这是网卡设备,只是个名称不必纠结.通常服务器会有多个网卡的,所以就有eth0 eth1 eth2 这样的名称,而且在一些系 ...
- paip.Log4j配置不起作用的解决
paip.Log4j配置不起作用的解决 1.jar包里的log4j配置 看累挂jar,真的有个" webservices-rt.jar\com\sun\org\apache\xml\inte ...
- js程序设计03——面向对象
ECMAScript中有2中属性:数据属性.访问器属性. 数据属性是为了指定某对象的指定key上的一些行为,比如value是否可删除.修改.key可循环遍历等特点.而访问器属性不包含数据值,包含一堆g ...
- fir.im Weekly - 每个程序员都应当拥有的技能树
本周收集了一些优秀的 iOS & Android 开发资源和程序员 IT 技能拓展的 Tips. 知道创宇研发技能表 v3.0 作为程序员可能都听说过[知道创宇],他们是一家黑客文化浓厚的安全 ...
- iOS App 研发的最后冲刺:内测与部署
当开发者历经磨难.披荆斩棘,完成了一个iOS项目后,最后的临门一脚就是应用的内测.部署.那么,在这最后的射门动作中,都有哪些地方需要开发者注意?有哪些方式能够更好地帮助我们进行iOS应用的发布部署? ...
- Quartz定时任务学习(一)简单任务
学习quartz首先了解三个概念: 调度器:负责调度作业和触发器: 触发器:设置作业执行的时间.参数.条件等:(简单触发器和Cron触发器) 作业:定时任务内容,被执行的程序: 下载必要的jar包,直 ...
- lpxelinux启动linux
搭建环境: boot file 指定 lpxelinux.0 拷贝 lpxelinux.0 和 ldlinux.c32 到 tftp目录下. 新建pxelinux.cfg 文件夹, 里面放 ...
- layer-list实现只有左、右和下边框的圆角矩形
项目中需要实现如下效果的布局 也就是一个左右下角带圆角,上方不带圆角的白色背景矩形,而且只有左.右和下边框,颜色为浅灰色. 当然,切一个.9图片作为背景也能实现,但是能用代码实现的还是尽量用代码实现, ...
- Eclipse 基于接口编程的时候,快速跳转到实现类的方法(图文)
Eclipse 基于接口编程的时候,要跳转到实现类很麻烦,其实Eclipse已经实现该功能. 只要按照Ctrl键,把鼠标的光标放在要跳转的方法上面,第一个是跳转到接口里面,第二个方法是跳转到实现类的位 ...