您的位置:首页 > 编程语言 > Java开发

spring配置文件中autowire详解

2016-06-11 12:49 495 查看
这个属性对应的值有以下几种



常用的是byName和byType,我来具体说说这两种值的区别与作用。

实例(DAO、Implements、Service三者之间的关系)

public class UserDAOImpl implements UserDAO{
private int daoId;
public int getDaoId() {
return daoId;
}
public void setDaoId(int daoId) {
this.daoId = daoId;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "daoId="+daoId;
}
}


public class UserService {
private UserDAO userDAO = new UserDAOImpl();

public UserDAO getUserDAO() {
return userDAO;
}

public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}

public void add(User user) {
this.userDAO.save(user);
}
}


public class SpringTest {
@Test
public void testAdd() throws Exception{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
UserService userService=(UserService) applicationContext.getBean("userService");
System.out.println(userService.getUserDAO());
}
}


daoId作用

之所以设置了个daoId变量,是为了在自动装配时,判断到底是哪个bean被装配了。查看daoId变量值即可知道。重写toString方法是为了输出daoId的值

byName

顾名思义,即通过名字来自动装配。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="userDAOImpl1" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="1"></property>
</bean>
<bean id="userDAOImpl2" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="2"></property>
</bean>
<bean id="userService" class="com.service.UserService" scope="prototype" autowire="byName">
</bean>
</beans>


可以看到,我们设置了2个UserDOAImpl的bean,取名为userDAOImpl1与userDAOImpl2加以区分,并且赋值2个daoId的变量值分别为1和2。那么这里的byName到底是指哪里的name呢?是指UserService当中UserDAOImpl的对象名,通过我们实例中的代码可以看到,对象名为userDAO,可是这2个bean都不是这个名字。所以运行的结果为

daoId=0

所以,如果想使用byName值,必须有一个id为userDAO的bean,才能被自动装配。现在我们做如下修改:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="userDAO" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="1"></property>
</bean>
<bean id="userDAOImpl2" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="2"></property>
</bean>
<bean id="userService" class="com.service.UserService" scope="prototype" autowire="byName">
</bean>
</beans>


查看输出结果

daoId=1

byType

现在,我们将配置文件进行修改

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="userDAOImpl1" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="1"></property>
</bean>
<bean id="userDAOImpl2" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="2"></property>
</bean>
<bean id="userService" class="com.service.UserService" scope="prototype" autowire="byType">
</bean>
</beans>


运行查看结果

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in class path resource [beans.xml]:
Unsatisfied dependency expressed through bean property 'userDAO': : No qualifying bean of type [com.dao.UserDAO] is defined: expected single matching bean
but found 2: userDAOImpl1,userDAOImpl2; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of
type [com.dao.UserDAO] is defined: expected single matching bean but found 2: userDAOImpl1,userDAOImpl2
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1303)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
at com.test.SpringTest.testAdd(SpringTest.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.dao.UserDAO] is defined: expected single matching bean but found 2: userDAOImpl1,userDAOImpl2
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1288)
... 30 more


通过错误代码提示可以看到,spring找到了2个同类型的bean,所以无法判断到底是哪个是用户所需要的bean.现在我们只留下一个bean

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="userDAOImpl1" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="1"></property>
</bean>
<bean id="userService" class="com.service.UserService" scope="prototype" autowire="byType">

9b1b
</bean>
</beans>

运行查看结果

daoId=1

通过实例代码可以知道,我们的UserService用的实现类是UserDAOImpl,并且只匹配到了一个对应的类,所以成功匹配。

总结:

byName是指在service中实现类的对象名

byType   是指在service中实现类的类名是否与bean的class一致

在实际开发中,并不建议使用自动装配,因为需要小心谨慎,很容易出现问题。推荐使用手动装配

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="userDAOImpl1" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="1"></property>
</bean>
<bean id="userDAOImpl2" class="com.dao.impl.UserDAOImpl">
<property name="daoId" value="2"></property>
</bean>
<bean id="userService" class="com.service.UserService" scope="prototype">
<property name="userDAO" ref="userDAOImpl1"/>
</bean>
</beans>


这样无论多少个相同类型的bean都不会出现问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  autowire byName byType