首页 > 代码库 > Spring入门第十六课
Spring入门第十六课
接上一次讲课
先看代码:
package logan.spring.study.annotation.repository; public interface UserRepository { void save(); }
package logan.spring.study.annotation.repository; import org.springframework.stereotype.Repository; @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); } }
package logan.spring.study.annotation.service; import org.springframework.stereotype.Service; import logan.spring.study.annotation.repository.UserRepository; @Service public class UserService { private UserRepository userRepository; public void add(){ System.out.println("UserService add..."); userRepository.save(); } }
package logan.spring.study.annotation.controller; import org.springframework.stereotype.Controller; import logan.spring.study.annotation.service.UserService; @Controller public class UserController { UserService userService; public void execute(){ System.out.println("UserController execute..."); userService.add(); } }
<?xml version="1.0" encoding="UTF-8"?> <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" 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-4.3.xsd"> <context:component-scan base-package="logan.spring.study.annotation"> </context:component-scan> </beans>
package logan.spring.study.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import logan.spring.study.annotation.controller.UserController; import logan.spring.study.annotation.repository.UserRepository; import logan.spring.study.annotation.service.UserService; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml"); // TestObject to = (TestObject) ctx.getBean("testObject"); // System.out.println(to); UserController userController = (UserController) ctx.getBean("userController"); System.out.println(userController); userController.execute(); // UserService userService = (UserService) ctx.getBean("userService"); // System.out.println(userService); // UserRepository userRepository = (UserRepository) ctx.getBean("userRepository"); // System.out.println(userRepository); } }
输出结果:
五月 27, 2017 11:15:37 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 11:15:37 CST 2017]; root of context hierarchy 五月 27, 2017 11:15:37 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] Exception in thread "main" logan.spring.study.annotation.controller.UserController@78ac1102 UserController execute... java.lang.NullPointerException at logan.spring.study.annotation.controller.UserController.execute(UserController.java:13) at logan.spring.study.annotation.Main.main(Main.java:18)
可以看到空指针异常,因为没有办法调用userController.execute();
组件装配
<context:component-scan>元素还会自动注册AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired和@Resource,@Inject注解的属性。
使用@Autowired自动装配Bean
@Autowired注解自动装配具有兼容类型的单个Bean属性:
-构造器,普通字段(即使是非public),一切具有参数的方法都可以应用@Autowired注解
-默认情况下,所有使用@Autowired注解的属性都要被设置,当Spring找不到匹配度Bean装配属性时,会抛出异常,若某一属性允许不被设置,可以设置@Autowired注解的required属性为false.
-默认情况下,当IOC容器里存在多个类型兼容的Bean时,通过类型的自动装配将无法工作,此时可以在@Qualifiter注解里面提供Bean的名称,Spring允许对方法的入参标注@Qualifiter已指定注入Bean的名称。
-@Autowired注解也可以应用在数组类型的属性上,此时Spring将会把所有匹配的Bean警醒自动装配。
-@Autowired注解也可以应用在集合属性上,此时Spring读取该集合的类型信息,然后自动装配所有与之兼容的Bean。
-@Autowired注解用在java.util.map上时,若该Map的键值为String,那么Spring将自动装配与之Map值类型兼容的Bean,此时Bean的名称作为键值。
看如下代码:
package logan.spring.study.annotation.repository; public interface UserRepository { void save(); }
package logan.spring.study.annotation.repository; import org.springframework.stereotype.Repository; @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); } }
package logan.spring.study.annotation.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import logan.spring.study.annotation.repository.UserRepository; @Service public class UserService { @Autowired private UserRepository userRepository; public void add(){ System.out.println("UserService add..."); userRepository.save(); } }
package logan.spring.study.annotation.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import logan.spring.study.annotation.service.UserService; @Controller public class UserController { @Autowired UserService userService; public void execute(){ System.out.println("UserController execute..."); userService.add(); } }
<?xml version="1.0" encoding="UTF-8"?> <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" 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-4.3.xsd"> <context:component-scan base-package="logan.spring.study.annotation"> </context:component-scan> </beans>
package logan.spring.study.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import logan.spring.study.annotation.controller.UserController; import logan.spring.study.annotation.repository.UserRepository; import logan.spring.study.annotation.service.UserService; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml"); // TestObject to = (TestObject) ctx.getBean("testObject"); // System.out.println(to); UserController userController = (UserController) ctx.getBean("userController"); System.out.println(userController); userController.execute(); // UserService userService = (UserService) ctx.getBean("userService"); // System.out.println(userService); // UserRepository userRepository = (UserRepository) ctx.getBean("userRepository"); // System.out.println(userRepository); } }
输出结果:
五月 27, 2017 12:16:53 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 12:16:53 CST 2017]; root of context hierarchy 五月 27, 2017 12:16:53 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] logan.spring.study.annotation.controller.UserController@704d6e83 UserController execute... UserService add... UserRepository Save...
在看如下代码:
package logan.spring.study.annotation; import org.springframework.stereotype.Component; @Component public class TestObject { }
package logan.spring.study.annotation.repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import logan.spring.study.annotation.TestObject; @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Autowired private TestObject testObject; @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); System.out.println(testObject); } }
package logan.spring.study.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import logan.spring.study.annotation.controller.UserController; import logan.spring.study.annotation.repository.UserRepository; import logan.spring.study.annotation.service.UserService; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml"); // TestObject to = (TestObject) ctx.getBean("testObject"); // System.out.println(to); UserController userController = (UserController) ctx.getBean("userController"); System.out.println(userController); userController.execute(); // UserService userService = (UserService) ctx.getBean("userService"); // System.out.println(userService); // UserRepository userRepository = (UserRepository) ctx.getBean("userRepository"); // System.out.println(userRepository); } }
输出结果为:
五月 27, 2017 1:22:00 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:21:59 CST 2017]; root of context hierarchy 五月 27, 2017 1:22:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] logan.spring.study.annotation.controller.UserController@43a0cee9 UserController execute... UserService add... UserRepository Save... logan.spring.study.annotation.TestObject@eb21112
如果没有TestObject就会出错,如下:
package logan.spring.study.annotation; public class TestObject { }
输出结果为:
五月 27, 2017 1:25:00 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:25:00 CST 2017]; root of context hierarchy 五月 27, 2017 1:25:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] 五月 27, 2017 1:25:00 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh 警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userController‘: Unsatisfied dependency expressed through field ‘userService‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService‘: Unsatisfied dependency expressed through field ‘userRepository‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userRepository‘: Unsatisfied dependency expressed through field ‘testObject‘; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.TestObject‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userController‘: Unsatisfied dependency expressed through field ‘userService‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService‘: Unsatisfied dependency expressed through field ‘userRepository‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userRepository‘: Unsatisfied dependency expressed through field ‘testObject‘; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.TestObject‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at logan.spring.study.annotation.Main.main(Main.java:12) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService‘: Unsatisfied dependency expressed through field ‘userRepository‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userRepository‘: Unsatisfied dependency expressed through field ‘testObject‘; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.TestObject‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 15 more Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userRepository‘: Unsatisfied dependency expressed through field ‘testObject‘; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.TestObject‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 28 more Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.TestObject‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 41 more
如果没有TestObject,还想让编译成功,如下:
package logan.spring.study.annotation.repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import logan.spring.study.annotation.TestObject; @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Autowired(required=false) private TestObject testObject; @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); System.out.println(testObject); } }
输出结果为:
五月 27, 2017 1:29:07 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:29:07 CST 2017]; root of context hierarchy 五月 27, 2017 1:29:07 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] logan.spring.study.annotation.controller.UserController@704d6e83 UserController execute... UserService add... UserRepository Save... null
如果有好几个类型相同的Bean,会出错吗?
看如下代码:
package logan.spring.study.annotation.repository; import org.springframework.stereotype.Repository; @Repository public class UserJdbcRepository implements UserRepository{ @Override public void save() { // TODO Auto-generated method stub System.out.println("UserJdbcRepository save...."); } }
package logan.spring.study.annotation.repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import logan.spring.study.annotation.TestObject; @Repository public class UserRepositoryImpl implements UserRepository { @Autowired(required=false) private TestObject testObject; @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); System.out.println(testObject); } }
这样会运行出错:
五月 27, 2017 1:33:57 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:33:57 CST 2017]; root of context hierarchy 五月 27, 2017 1:33:57 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] 五月 27, 2017 1:33:58 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh 警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userController‘: Unsatisfied dependency expressed through field ‘userService‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService‘: Unsatisfied dependency expressed through field ‘userRepository‘; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.repository.UserRepository‘ available: expected single matching bean but found 2: userJdbcRepository,userRepositoryImpl Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userController‘: Unsatisfied dependency expressed through field ‘userService‘; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService‘: Unsatisfied dependency expressed through field ‘userRepository‘; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.repository.UserRepository‘ available: expected single matching bean but found 2: userJdbcRepository,userRepositoryImpl at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at logan.spring.study.annotation.Main.main(Main.java:12) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘userService‘: Unsatisfied dependency expressed through field ‘userRepository‘; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.repository.UserRepository‘ available: expected single matching bean but found 2: userJdbcRepository,userRepositoryImpl at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 15 more Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘logan.spring.study.annotation.repository.UserRepository‘ available: expected single matching bean but found 2: userJdbcRepository,userRepositoryImpl at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 28 more
解决方法就是指定userRepository
package logan.spring.study.annotation.repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import logan.spring.study.annotation.TestObject; @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { @Autowired(required=false) private TestObject testObject; @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); System.out.println(testObject); } }
输出结果为:
五月 27, 2017 1:37:26 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:37:26 CST 2017]; root of context hierarchy 五月 27, 2017 1:37:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] logan.spring.study.annotation.controller.UserController@4d1b0d2a UserController execute... UserService add... UserRepository Save... null
还可以在UserService里面指定:
package logan.spring.study.annotation.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import logan.spring.study.annotation.repository.UserRepository; @Service public class UserService { @Autowired @Qualifier("userRepositoryImpl") private UserRepository userRepository; public void add(){ System.out.println("UserService add..."); userRepository.save(); } }
package logan.spring.study.annotation.repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import logan.spring.study.annotation.TestObject; @Repository public class UserRepositoryImpl implements UserRepository { @Autowired(required=false) private TestObject testObject; @Override public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); System.out.println(testObject); } }
输出结果为:
五月 27, 2017 1:41:07 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:41:07 CST 2017]; root of context hierarchy 五月 27, 2017 1:41:07 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] logan.spring.study.annotation.controller.UserController@67b467e9 UserController execute... UserService add... UserRepository Save... null
对于set方法也是可以的,如下看代码:
package logan.spring.study.annotation.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import logan.spring.study.annotation.repository.UserRepository; @Service public class UserService { private UserRepository userRepository; @Autowired @Qualifier("userRepositoryImpl") public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } public void add(){ System.out.println("UserService add..."); userRepository.save(); } }
输出结果为:
五月 27, 2017 1:42:58 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@42110406: startup date [Sat May 27 13:42:58 CST 2017]; root of context hierarchy 五月 27, 2017 1:42:58 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-annotation.xml] logan.spring.study.annotation.controller.UserController@545997b1 UserController execute... UserService add... UserRepository Save... null
还可以放在入参的里面:
package logan.spring.study.annotation.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import logan.spring.study.annotation.repository.UserRepository; @Service public class UserService { private UserRepository userRepository; @Autowired public void setUserRepository(@Qualifier("userRepositoryImpl") UserRepository userRepository) { this.userRepository = userRepository; } public void add(){ System.out.println("UserService add..."); userRepository.save(); } }
Spring入门第十六课