1.spring为什么要使用自动装配
使用了spring的自动装配就不用再在bean的配置文件中指定类的依赖关系,也就不需要在bean标签里面使用property标签来指定所依赖的bean了;只用起来比较方便。
2.spring自动装配时的配置文件如何配置
可以有下面一种情况,在spring的配置文件声明处声明自动装配是按name来自动装配的
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
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/ng-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="byName" default-lazy-init="true">
3.配置文件中的bean如何声明
在spring的配置文件中的bean就不用使用property属性来指定所依赖的bean了,只用把bean配置成单个的就行了,如下所示
4.在代码中如何使用自动装配
4.1.如果使用了@Autowired注解,那么就不用在代码中使用get set方法就可注入所依赖的bean,如下所示
/**
* 注入各service
*/
@Autowired
private TransactionMessageService transactionMessageService;
@Autowired
private ClientUserService clientUserService;
@Autowired
private ExternalSysInfoService externalSysInfoService;
@Autowired
private ExternalSystemsUserService externalSystemsUserService;
@Autowired
private ExternalSysUserInterfaceInfoService externalSysUserInterfaceInfoService;
@Autowired
private InterfaceInfoService interfaceInfoService;
@Autowired
private GeCodeService geCodeService;
@Autowired
private WebService webService;
4.2.如果没有使用@Autowired的注解那么就需要在代码中使用get set方法来显式注入,如下所示
private GeProductPictureDetailService geProductPictureDetailService;//自定义服务接口
private GeProductPictureDetail geProductPictureDetail;//自定义实体类
public GeProductPictureDetailService getGeProductPictureDetailService() {
return geProductPictureDetailService;
}
public void setGeProductPictureDetailService(
GeProductPictureDetailService geProductPictureDetailService) {
this.geProductPictureDetailService = geProductPictureDetailService;
}
public GeProductPictureDetail getGeProductPictureDetail() {
return geProductPictureDetail;
}
public void setGeProductPictureDetail(
GeProductPictureDetail geProductPictureDetail) {
this.geProductPictureDetail = geProductPictureDetail;
}
其中如上所示如果是byName的方式自动装配的,那么在代码中的属性名最好跟bean 的id一样,这样可以在eclipse中自动生成get set方法,
其实自动装配时spring找的是代码中的set方法,例如在代码中如果想使用spring配置文件中的一个id为id="geProductService",而正常的做法就是在代码中声明一个名为geProductService的属性,然后自动生成setGeProductService这样的方法,实现自动装配的依赖注入,而假如在代码中想使用id为id="geProductService"的bean,在代码中呢又声明了一个属性名为fangTest的属性,但是类型是GeProductService的,即private GeProductService fangTest,并且还想在代码中使用geProductService为fangTest赋值,也就是说在在代码中使用id="geProductService"的bean但是呢在代码中的属性名是自己随意指定的,那么在使用get set方法注入时需要有setGeProductService而不是setFangTest这样的set方法,如下所示
private GeProductService geProductService;
public void setGeProductService(GeProductService geProductService){
this.geProductService = geProductService;
}
或者
private GeProductService fangTest;
public void setGeProductService(GeProductService geProductService1){
this.fangTest = geProductService1;
}
使用了@Autowired,但是在配置文件里还用,没有getset报出的异常
配置文件的书写
代码中的书写
//订单支付流水日志表Service
@Autowired
private PaymentLogService paymentLogService;
以上是用了@Autowired,但是在代码里没有get set报以下异常信息
2013-9-19 14:38:58 org.apache.catalina.core.StandardContext listenerStart
严重: Exception sending context initialized event to listener instance of class com.icbc.emall.common.utils.SpringContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'refundResultHandler' defined in class path resource [emall/emall-service.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'paymentLogService' of bean class [com.icbc.emall.refund.service.impl.RefundResultHandlerImpl]: Bean property 'paymentLogService' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1423)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1128)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at com.icbc.emall.common.utils.SpringContextLoaderListener.contextInitialized(SpringContextLoaderListener.java:61)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4791)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'paymentLogService' of bean class [com.icbc.emall.refund.service.impl.RefundResultHandlerImpl]: Bean property 'paymentLogService' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1042)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:902)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1420)
... 23 more
5.自动装配byType
通过类型匹配的方式自动装配,但是配置文件中一个类型的类只能配置一个bean,如果一个实现类配置了2个bean就会报出项目的异常:
expected single matching bean but found 2:[userDAO,userDAO2]
示例代码(会报出上面异常的示例代码):
public class UserService {
private UserDAO userDAO;
public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
当然,通过该代码也可以看出,如果没有使用注解@Autoware,在代码中如果要想使用bean,即使是自动装配的也还是需要有set (get方法其实不需要也可以的,但是留着也无妨,纯属个人理解)方法的。
6.自动装配的其他类型constructor,autodetect
类型除了byName,byType其他类型都很少用,在此不在赘述(只写有效的博客)。