1.Spring提供哪些配置形式?
Spring 对 Java配置的支持是由@Configuration注解和@Bean注解来实现的。
- 被@Configuration所注解的类则表示这个类的主要目的是作为bean定义的资源。被@Configuration 声明的类可以通过在同一个类的内部调用@bean 方法来设置嵌入 bean 的依赖关系。
- 由@Bean注解的方法将会实例化、配置和初始化一个新对象,这个对象将由 Spring 的 IOC 容器来管理。@Bean 声明所起到的作用与
<bean>
元素类似。
最简单的@Configuration 声明类请参考下面的代码:
@Configuration
public class AppConfig{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
对于上面的@Beans配置文件相同的XML配置文件如下:
<beans>
<bean id="myService" class="com.my.services.MyServiceImpl"/>
</beans>
上述配置方式的实例化方式如下:利用AnnotationConfigApplicationContext 类进行实例化
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
要使用组件组建扫描,仅需用@Configuration进行注解即可:
@Configuration
@ComponentScan(basePackages = "com.my")
public class AppConfig { }
在上面的例子中,com.my包首先会被扫到,然后再容器内查找被@Component 声明的类,找到后将这些类按照Spring bean定义进行注册。
如果你要在你的 web 应用开发中选用上述的配置的方式的话 , 需要用AnnotationConfigWebApplicationContext 类来读取配置文件,可以用来配置Spring 的Servlet监听器ContrextLoaderListener或者Spring MVC的DispatcherServlet。
<web-app>
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.my.AppConfig</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param> <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.my.web.MVCConfig</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/web/*</url-pattern>
</servlet-mapping>
</web-app>
2.如何使用XML配置方式配置Spring?
在Spring框架中,依赖和服务需要在专门的配置文件来实现,常用的就是XML格式的配置文件。SpringXML配置的主要目的时候是使所有的Spring组件都可以用xml文件的形式来进行配置。这意味着不会出现其他的Spring配置类型(比如声明的方式或基于Java Class的配置方式)。
Spring 的 XML 配置方式是使用被 Spring 命名空间的所支持的一系列的 XML标签来实现的。Spring有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc和aso。比如下面就是一个使用 beans 标签的示例:
<beans>
<!-- JSON Support -->
<bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
</beans>
下面这个 web.xml 仅仅配置了DispatcherServlet,这最简单的配置便能满足应用程序配置运行时组件的需求。
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.怎样用注解的方式配置Spring?
Spring在2.5版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代XML方式的 bean 描述,可以将 bean 描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。
注解注入将会被容器在 XML 注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。
注解装配在Spring中是默认关闭的。所以需要在Spring文件中配置一下才能使用基于注解的装配模式。如果你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置。
<beans>
<context:annotation-config/>
</beans>
在标签配置完成以后,就可以用注解的方式在Spring中向属性、方法和构造方法中自动装配变量。下面是几种比较重要的注解类型:
- @Required:该注解应用于设值方法。
- @Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。
- @Qualifier:该注解和@Autowired注解搭配使用,用于消除特定bean自动装配的歧义。
- JSR-250Annotations: Spring 支持基于 JSR-250 注解以下注解,@Resource、@PostConstruct和 @PreDestroy。
4.在Java中依赖注入有哪些方式?
- 构造器注入
- Setter方法注入
- 接口注入
也可用”util:”命名空间来从 properties文件中创建出一个propertiesbean,然后利用setter方法注入bean的引用。
5.构造方法注入和设值注入的区别?
请注意以下明显的区别:
- 在设值注入方法支持大部分的依赖注入,如果我们仅需要注入int、string和long型的变量,我们不要用设值的方法注入。对于基本类型,如果我们没有注入的话,可以为基本类型设置默认值。在构造方法注入不支持大部分的依赖注入,因为在调用构造方法中必须传入正确的构造参数,否则的话为报错。
- 设值注入不会重写构造方法的值。如果我们对同一个变量同时使用了构造方法注入又使用了设置方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。很明显,因为构造方法尽在对象被创建时调用。
- 在使用设值注入时有可能还不能保证某种依赖是否已经被注入,也就是说这时对象的依赖关系有可能是不完整的。而在另一种情况下,构造器注入则不允许生成依赖关系不完整的对象。
- 在设值注入时如果对象 A 和对象 B互相 赖 ,在创建对象A时 Spring 会抛出sObjectCurrentlyInCreationException异常,因为在B对象被创建之前A对象是不能被创建的,反之亦然。所以 Spring用设值注入的方法解决了循环依赖的问题,因对象的设值方法是在对象被创建之前被调用的。
6.请举例说明如何在Spring中注入一个Java 集合?
Spring提供了以下四种集合类的配置元素:
- list: 该标签用来装配可重复的list值。
- set: 该标签用来装配没有重复的set值。
- map: 该标签可用来注入键和值可以为任何类型的键值对。
- props: 该标签支持注入键和值都是字符串类型的键值对。
下面看一下具体的例子:
<beans>
<bean id="javaCollection" class="com.my.JavaCollection">
<property name="customList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</list>
</property>
<property name="customSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</set>
</property>
<property name="customMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="UK"/>
</map>
</property>
<property name="customProperies">
<props>
<prop key="admin">admin@my.com</prop>
<prop key="support">support@my.com</prop>
</props>
</property>
</bean>
</beans>
7.如何向Spring Bean中注入java.util.Properties?
可以使用如下面代码所示的标签:
<bean id="adminUser" class="com.my.common.Customer">
<property name="emails">
<props>
<prop key="admin">admin@my.com</prop>
<prop key="support">support@my.com</prop>
</props>
</property>
</bean>
8.请解释Spring Bean的自动装配?
在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring容器还可以自动装配合作关系bean之间的关联关系。这意味着 Spring可以通过向BeanFactory 中注入的方式自动搞定bean之间的依赖关系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。
下面的XML配置文件表明了如何根据名称将一个bean设置为自动装配:
<bean id="employeeDAO" class="com.my.EmployeeDAOImpl" autowire="byName" />
除了bean配置文件中提供的自动装配模式,还可以使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在按照如下的配置方式在Spring配置文件进行配置才可以使用。
<context:annotation-config />
也可以通过在配置文件中配置AutowiredAnnotationBeanPostProcessor 达到相同的效果。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
配置好以后就可以使用@Autowired来标注了。
@Autowired
public EmployeeDAOImpl ( EmployeeManager manager ) {
this.manager = manager;
}
9.自动装配有哪些局限性?
自动装配有如下局限性:
- 重写:你仍然需要使用 和
<property>
设置指明依赖,这意味着总要重写自动装配。 - 原生数据类型:你不能自动装配简单的属性,如原生类型、字符串和类。
- 模糊特性:自动装配总是没有自定义装配精确,因此,如果可能尽量使用自定义装配。
10.请解释各种自动装配模式的区别?
在Spring框架中共有5种自动装配,让我们逐一分析。
- no:这是Spring 框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在 bean定义中用标签明确的设置依赖关系。
- byName:该选项可以根据 bean名称设置依赖关系。当向一个 bean中自动装配一个属性时,容器将根据 bean的名称自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
- byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据 bean 的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
- constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的 bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
- autodetect:该模式自动探测使用构造器自动装配或者byType 自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。