现在的位置: 首页 > 综合 > 正文

spring自动装配的学习研究各种情况(未完待续…..)

2019年04月24日 ⁄ 综合 ⁄ 共 9226字 ⁄ 字号 评论关闭

1.spring为什么要使用自动装配

  使用了spring的自动装配就不用再在bean的配置文件中指定类的依赖关系,也就不需要在bean标签里面使用property标签来指定所依赖的bean了;只用起来比较方便。

2.spring自动装配时的配置文件如何配置

  可以有下面一种情况,在spring的配置文件声明处声明自动装配是按name来自动装配的

<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: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配置成单个的就行了,如下所示

<bean id="carProposalAction" class="cn.com.ebusiness.sale.web.CarProposalAction" scope="prototype" />
<bean id="ePolicyAction" class="cn.com.ebusiness.service.epolicy.web.EPolicyAction" scope="prototype"></bean>
<bean id="propertyPolicy" class="cn.com.ebusiness.service.policyService.web.PropertyPolicyAction" scope="prototype"></bean>
<bean id="pensionPolicyAction" class="cn.com.ebusiness.service.policyService.web.PensionPolicyAction" scope="prototype"></bean>
<bean id="geUserPersonalAction" class="cn.com.ebusiness.service.user.personal.web.GeUserPersonalAction" scope="prototype"></bean>
<bean id="enterpriceAction" class="cn.com.ebusiness.service.user.enterprice.web.EnterpriceAction" scope="prototype"></bean>
<bean id="saleManAction" class="cn.com.ebusiness.service.user.saleMan.web.SaleManAction" scope="prototype"></bean>
<bean id="complaintAction" class="cn.com.ebusiness.service.communicationService.web.ComplaintAction" scope="prototype"></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,但是在配置文件里还用<property>,没有getset报出的异常

配置文件的书写

 

    <bean id="refundResultHandler" class="com.icbc.emall.refund.service.impl.RefundResultHandlerImpl">
     <property name="paymentLogService" ref="paymentLogService"/>
    </bean>

代码中的书写

//订单支付流水日志表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]

示例代码(会报出上面异常的示例代码):

 

<bean name="userDAO" class="com.a.dao.impl.UserDAOImpl">
<property name="daoId" value="1"></property>
</bean>

<bean name="userDAO2" class="com.a.dao.impl.UserDAOImpl">
<property name="daoId" value="2"></property>
</bean>

<bean id="userService" class="com.a.service.UserService" scope="prototype" autowire="byType">
</bean>

 

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其他类型都很少用,在此不在赘述(只写有效的博客)。

 

参考:http://blog.csdn.net/zy609398738/article/details/7451724

抱歉!评论已关闭.