接上一次讲课

先看代码:

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入门第十六课的更多相关文章

  1. Spring入门第十九课

    后置通知 看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int add(int i, int j ...

  2. Spring入门第十八课

    Spring AOP AspectJ:Java社区里最完整最流行的AOP框架 在Spring2.0以上的版本中,可以使用基于AspectJ注解或者基于XML配置的AOP 看代码: package lo ...

  3. Spring入门第十五课

    泛型依赖注入 看代码: package logan.spring.study.generic.di; public class BaseRepository<T> { } package ...

  4. Spring入门第十四课

    基于注解的方式配置bean(基于注解配置Bean,基于注解来装配Bean的属性) 在classpath中扫描组件 组件扫描(component scanning):Spring能够从classpath ...

  5. Spring入门第十二课

    Bean的配置方法 通过工厂方法(静态工厂方法&实例工厂方法),FactoryBean 通过调用静态工厂方法创建Bean 调用静态工厂方法创建Bean是将对象创建的过程封装到静态方法中,当客户 ...

  6. CTF---Web入门第十六题 天下武功唯快不破

    天下武功唯快不破分值:10 来源: 北邮天枢战队 难度:易 参与人数:10787人 Get Flag:2264人 答题人数:3373人 解题通过率:67% 看看响应头 格式:CTF{ } 解题链接: ...

  7. Spring入门第十课

    Spring表达式语言:SpEL Spring表达式语言(简称SpEL)是一个支持运行时查询和操作对象图的强大的表达式语言. 语法类似于EL:SpEL使用#{...}作为定界符,所有在大括号中的字符都 ...

  8. Spring入门第二十六课

    Spring中的事务管理 事务简介 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性. 事务就是一系列的动作,他们被当做一个单独的工作单元,这些动作要么全部完成,要么全部不起 ...

  9. Android入门第十六篇之Style与Theme [转]

    本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 越来越多互联网企业都在Android平台上部署其客户端,为了提升用户体验,这些客户端都做得布局合理而且美观.. ...

随机推荐

  1. Notepad工具使用小技巧

    工欲善其事必先利其器 Notepad++是个很不错的文本编辑工具,掌握它的使用技巧可以提高我们工作的效率.见如下: 比较常用的罗列如下:(如果有更好的建议可以留言哈) 1: 添加书签 CTRL+F2 ...

  2. XShell 连接 vm虚拟机中的redhat Linux系统

    选择的是nat链接,因为nat链接是没有网络的情况下,也是可以链接操作的,当然bridge也可以,那我就从第一步开始; 因为有的人可能改过电脑上的虚拟适配器的ip地址,导致和虚拟机默认的不一样了.如果 ...

  3. 性能测试--siege

    siege 这是Linux系统下的一个测试工具,完全使用C语言实现,可以对HTTP和FTP服务器进行负载和性能测试.通过使用Siege 提供的功能,可以很容易的制定测试计划:包括规定使用并发用户数.重 ...

  4. php中$t=date()函数参数意义及时间更改

    php中date()函数用的最多的是:date('Y-m-d H:i:s', time());  这里面的参数意义分别是:Y - 年,四位数字; 如: "2016":m - 月份, ...

  5. 【题解】Coins(二进制拆分+bitset)

    [题解]Coins(二进制拆分+bitset) [vj] 俗话说得好,bitset大法吼啊 这道题要不是他多组数据卡死了我复杂度算出来等于九千多万的选手我还不会想这种好办法233 考虑转移的实质是怎样 ...

  6. IDEA tomcat三步实现热部署

    IDEA tomcat三步实现热部署 添加Artifacts选项 添加Artifacts选项,XXXwar 和 XXXwar exploded二选一,若要热部署须选后者. 设置tomcat部署方案 设 ...

  7. 使用electron静默打印

    1.使用electron打印的理由 很多情况下程序中使用的打印都是用户无感知的.并且想要灵活的控制打印内容,往往需要借助打印机给我们提供的api再进行开发,这种开发方式非常繁琐,并且开发难度较大. e ...

  8. csrf防范笔记

    1.验证Http的refer字段 http有一个refer字段,用以记录该http请求的来源地址 好处: 简单便捷,后台开发人员只需要设置一个拦截器 缺点: Referer 的值是由浏览器提供的,虽然 ...

  9. CodeChef - ANDMIN —— 线段树 (结点最多被修改的次数)

    题目链接:https://vjudge.net/problem/CodeChef-ANDMIN Read problems statements in Mandarin Chinese, Russia ...

  10. 使用.net实现ZooKeeper客户端

    最近在项目中用到ZooKeeper, 通过Java连接比较容易,.net项目就没那么容易,尤其对于不熟悉Linux的开发人员,这里写点搭建ZooKeeper测试环境的经验,供参考. 背景知识: Zoo ...