<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.xsd">
<bean id="..." class="...">
bean>
<bean id="..." class="...">
bean>
beans>
如上例,通过配置bean,完成类型注入。
注入的方法有三种:
setter注入
<bean id="exampleBean" class="examples.ExampleBean">
<property name="beanOne">
<ref bean="anotherExampleBean"/>
property>
<property name="beanTwo" ref="yetAnotherBean"/>
<property name="integerProperty" value="1"/>
bean>
构造方法注入
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg>
<ref bean="anotherExampleBean"/>
constructor-arg>
<constructor-arg ref="yetAnotherBean"/>
<constructor-arg type="int" value="1"/>
bean>
type是通过类型自动匹配,index是通过索引匹配。
接口注入(由于破坏了类的封装,所以不提倡使用)
id和name 存在些许不同,比如name 可以使用特殊字符。但是基本作用相同。
简单属性是指类似int,String这样的属性。
第一种方法:采用name+value直接将值注入。
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="masterkaoli"/>
bean>
第二种方法:通过p命名空间配置,更加简洁。但是据说IDEA等部分IDE才可以用。
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mydb"
p:username="root"
p:password="masterkaoli"/>
可以注入的集合包括List, Set, Map, 和 Properties。分别对应了标签
,
, , and
,集合标签都应该是在依赖注入的时候使用。
<props>
<prop key="administrator">[email protected]prop>
<prop key="support">[email protected]prop>
<prop key="development">[email protected]prop>
props>
<list>
value>a list element followed by a referencevalue>
<ref bean="myDataSource" />
list>
<map>
<entry key="an entry" value="just some string"/>
map>
<set>
<value>just some stringvalue>
<ref bean="myDataSource" />
set>
映射键或值的值或设置值也可以是以下任何元素: bean | ref | idref | list | set | map | props | value | null
空注入的标签为
如果两个bean之间的初始化顺序存在依赖关系,但是两个bean之间没有从属关系。那么就不可以设置ref来保证两个bean的初始化顺序,可以使用depends-on。设置一个或多个bean的名称来保证当前bean一定在这些bean之后完成初始化。
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
<property name="manager" ref="manager" />
bean>
让bean自动装配的方法是在
中设置autoware属性,属性的取值如下:
Mode | Explanation |
---|---|
no | (默认)无自动装配。 必须通过ref元素定义Bean引用。 不建议对较大的部署更改默认设置,因为明确指定协作者可以提供更好的控制和清晰度。 在某种程度上,它记录了系统的结构。 |
byName | 按属性名称自动装配。 Spring查找与需要自动装配的属性同名的bean。 例如,如果bean定义按名称设置为autowire,并且它包含master属性(即,它具有setMaster(…)方法),则Spring会查找名为master的bean定义,并使用它来设置 属性。 |
byType | 如果容器中只存在一个属性类型的bean,则允许自动装配属性。 如果存在多个,则抛出致命异常,这表示您不能对该bean使用byType自动装配。 如果没有匹配的bean,则没有任何反应; 该物业未设定。 |
constructor | 类似于byType,但适用于构造函数参数。 如果容器中没有构造函数参数类型的一个bean,则会引发致命错误。 |
byType和constructor的区别就在于,如果少了一个对应类型的bean,byType而言只是少装配了一个,对constructor来说将会引发错误。
还可以通过设置在
中设置default-autoware
来完成所有的bean的自动装配选项。
Scope | Description |
---|---|
singleton | 默认的选择,也就是单例。 |
prototype | 原型。每次通过工厂获取的都是一个新的实例。 |
request | 将单个bean定义范围限定为单个HTTP请求的生命周期; 也就是说,每个HTTP请求都有自己的bean实例,它是在单个bean定义的后面创建的。 仅在Web感知Spring ApplicationContext的上下文中有效。 |
session | 将单个bean定义范围限定为HTTP会话的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。 |
globalSession | 将单个bean定义范围限定为全局HTTP会话的生命周期。 通常仅在Portlet上下文中使用时有效。 仅在Web感知Spring ApplicationContext的上下文中有效。 |
application | 将单个bean定义范围限定为ServletContext的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。 |
websocket | 将单个bean定义范围限定为WebSocket的生命周期。 仅在Web感知Spring ApplicationContext的上下文中有效。 |
常用的仅仅是前两种。
lazy-init
设置lazy-init="true"
后,所有的bean不会马上在容器中实例化,而是在使用的时候实例化。
init-method 和destroy-method
通过设置这两个属性,容器对bean初始化的时候调用该init-method指定的方法,容器关闭的时候将会执行destroy-method指定的方法。
通过注解配置IOC容器注入类型,依赖注入等功能比配置XML实现要简单许多。
首先要在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"
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="kolo.spring" />
beans>
注释了*的地方是新加入的。
加入之后就可以在源码中使用Annotation,完成刚刚在XML中才能完成的任务了。
@Autowired
注释在需要自动装配的方法,构造方法,字段上。将会自动的在IOC容器中通过byType的方式自动的装配,完成依赖注入。
如果是在字段上注释,那就是接口注入。
@Qualifier
配置在字段前,方法的参数前,将会让自动装配通过byName的方式完成。
<bean class="example.SimpleMovieCatalog">
<qualifier value="main"/>
bean>
public void prepare(@Qualifier("main")MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
@Required
受该注释的影响的bean属性必须填充,否则将会产生错误。这样是为了将错误提前到编译期间。
__@Resource __
通过name属性指定bean名称,来注入属性。
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
@PostConstruct and @PreDestroy
通过注释在方法前面,效果等同于init-method 和destroy-method
@Component,@Service, @Controller,@Component
这三个注释在目前没有太大区别,同样都是标记产生bean,注入到容器中。
使用这三个标签完成类型注入,一定要设置XML,使spring扫描所有的源码。
设置base-package来扫描不同的package。
<context:component-scan base-package="org.example"/>
Aspect Oriental Program 面向切面编程
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:annotation-config/>
<context:component-scan base-package="kolo.spring" />
<aop:aspectj-autoproxy />
该注释用在类声明前,表明被标注的类可能包含pointcut,advice和instrodution。只有被IOC容器管理的类才能使用@Aspect。
形如:
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}
声明一个切口,切口名为方法名。切入方法定义在execution中。
前几个的意义很明显,@Around使用方法如下:
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
前面的配置是在源码中注释实现,还可以在XML配置文件中设置。
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
...
aop:aspect>
aop:config>
expression属性配置切面方法名,id是切面引用名。如果pointcut配置在
内,那么pointcut的作用域就属于该aspect内。
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..))"/>
pointcut-ref属性为所用pointcut的id,method为切入点方法名。
使用returns属性指定应将返回值传递到切面方法的参数的名称,如果使用,那么必须存在一个名为doAccessCheck并且存在retVal参数。
使用throwing属性指定应将异常传递到的参数的名称。
<aop:before pointcut-ref="businessService" method="monitor"/>
<aop:after-returning
pointcut-ref="dataAccessOperation"
returning="retVal"
method="doAccessCheck"/>
<aop:after-throwing
pointcut-ref="dataAccessOperation"
throwing="dataAccessEx"
method="doRecoveryActions"/>
<aop:around
pointcut-ref="businessService"
method="doBasicProfiling"/>