zoukankan      html  css  js  c++  java
  • Spring学习--通过注解配置 Bean (三)

    组件装配:

     <context:component-sacan> 元素还会自动注册 AutowiredAnnotationBeanPostProcesser 实例 , 该实例可以自动装配具有 @Autowired 和 @Resource 、 @Inject 注解的属性。

    使用 @Autowired 自动装配 Bean:

    @Autowired 注解自动装配具有兼容类型的单个 Bean 属性:

    • 构造器 , 普通字段(即使是非 public) , 一切具有参数的方法都可以用 @Autowired 注解。
    • 默认情况下 , 所有使用 @Autowired 注解的属性都需要被设置。当 Spring 找不到匹配的 bean 装配属性时 , 会抛出异常 , 若某一属性允许不被设置 , 可以设置 @Autowired 注解的 required 属性为 false。
    • 默认情况下 , 当 IOC 容器里存在多个类型兼容的 bean 时 , 通过类型的自动装配将无法工作 , 此时可以在 @Qualifier 注解里提供 bean 的名称。Spring 允许对方法的入参标注 @Qualifiter 已指定注入 bean 的名称。或在需要自动装配的注解中通过 value 属性值标识组件的名称。
    • @Autowired 注解也可以应用在数组类型的属性上 , 此时 Spring 将会把所有匹配的 bean 进行自动装配。
    • @Autowired 注解也可以应用在集合属性上 , 此时 Spring 读取该集合的类型信息 , 然后自动装配所有与之兼容的 bean。
    • @Autowired 注解用在 java.util.Map 上时 , 若该 Map 的键值为 String , 那么 Spring 将自动装配与之 Map 值类型兼容的 bean , 此时 bean 的名称作为键值。
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:context="http://www.springframework.org/schema/context"
     5        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     6        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
     7 
     8     <!-- 指定 Spring IOC 容器扫描的包 -->
     9     <context:component-scan base-package="com.itdjx.spring.annotation"/>
    10 
    11 </beans>
     1 package com.itdjx.spring.annotation.controller;
     2 
     3 import com.itdjx.spring.annotation.service.UserService;
     4 import org.springframework.stereotype.Controller;
     5 
     6 /**
     7  * @author Wáng Chéng Dá
     8  * @create 2017-03-03 9:28
     9  */
    10 @Controller
    11 public class UserController {
    12     private UserService userService;
    13 
    14     public void execute() {
    15         System.out.println("I am UserController's execute method...");
    16         userService.add();
    17     }
    18 }
     1 package com.itdjx.spring.annotation.service;
     2 
     3 import com.itdjx.spring.annotation.repository.UserRepository;
     4 import org.springframework.stereotype.Service;
     5 
     6 /**
     7  * @author Wáng Chéng Dá
     8  * @create 2017-03-03 9:26
     9  */
    10 @Service
    11 public class UserService {
    12 
    13     private UserRepository userRepository;
    14 
    15     public void add() {
    16         System.out.println("I am UserService's add method...");
    17         userRepository.sava();
    18     }
    19 }
     1 package com.itdjx.spring.annotation.repository;
     2 
     3 /**
     4  * @author Wáng Chéng Dá
     5  * @create 2017-03-03 9:23
     6  */
     7 public interface UserRepository {
     8 
     9     void sava();
    10 
    11 }
     1 package com.itdjx.spring.annotation.repository;
     2 
     3 import org.springframework.stereotype.Repository;
     4 
     5 /**
     6  * @author Wáng Chéng Dá
     7  * @create 2017-03-03 9:24
     8  */
     9 @Repository("userRepository")
    10 public class UserRepositoryImpl implements UserRepository {
    11 
    12     @Override
    13     public void sava() {
    14         System.out.println("I am UserRepositoryImpl's sava method...");
    15     }
    16 }
     1 package com.itdjx.spring.annotation;
     2 
     3 import com.itdjx.spring.annotation.controller.UserController;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 /**
     8  * @author Wáng Chéng Dá
     9  * @create 2017-03-03 9:34
    10  */
    11 public class Main {
    12 
    13     public static void main(String[] args) {
    14 
    15         ApplicationContext cxt = new ClassPathXmlApplicationContext("beans-annotation.xml");
    16         UserController userController = (UserController) cxt.getBean("userController");
    17         userController.execute();
    18 
    19     }
    20 }

    控制台输出:

    Exception in thread "main" java.lang.NullPointerException
    at com.itdjx.spring.annotation.controller.UserController.execute(UserController.java:16)
    at com.itdjx.spring.annotation.Main.main(Main.java:17)

    原因:IOC 容器中虽然每个 bean 节点都存在 , 但是没有引入到需要引入的 bean 节点中 , 需要将需要引入的 bean 节点引入相应的 bean 节点中。

     1 package com.itdjx.spring.annotation.controller;
     2 
     3 import com.itdjx.spring.annotation.service.UserService;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Controller;
     6 
     7 /**
     8  * @author Wáng Chéng Dá
     9  * @create 2017-03-03 9:28
    10  */
    11 @Controller
    12 public class UserController {
    13     @Autowired
    14     private UserService userService;
    15 
    16     public void execute() {
    17         System.out.println("I am UserController's execute method...");
    18         userService.add();
    19     }
    20 }
     1 package com.itdjx.spring.annotation.service;
     2 
     3 import com.itdjx.spring.annotation.repository.UserRepository;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Service;
     6 
     7 /**
     8  * @author Wáng Chéng Dá
     9  * @create 2017-03-03 9:26
    10  */
    11 @Service
    12 public class UserService {
    13 
    14     @Autowired
    15     private UserRepository userRepository;
    16 
    17     public void add() {
    18         System.out.println("I am UserService's add method...");
    19         userRepository.sava();
    20     }
    21 }

    控制台输出:

    I am UserController's execute method...
    I am UserService's add method...
    I am UserRepositoryImpl's sava method...

    假如我们将 IOC 容器中不存在的 bean 节点引入到 bean 节点中 , 会出现什么状况呢?

     1 package com.itdjx.spring.annotation;
     2 
     3 
     4 /**
     5  * @author Wáng Chéng Dá
     6  * @create 2017-03-03 8:44
     7  */
     8 
     9 public class TestObject {
    10 }
     1 package com.itdjx.spring.annotation.repository;
     2 
     3 import com.itdjx.spring.annotation.TestObject;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Repository;
     6 
     7 /**
     8  * @author Wáng Chéng Dá
     9  * @create 2017-03-03 9:24
    10  */
    11 @Repository("userRepository")
    12 public class UserRepositoryImpl implements UserRepository {
    13 
    14     @Autowired
    15     private TestObject testObject;
    16     @Override
    17     public void sava() {
    18         System.out.println("I am UserRepositoryImpl's sava method...");
    19         System.out.println(testObject);
    20     }
    21 }

    控制台输出:

    警告: 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 'com.itdjx.spring.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 'com.itdjx.spring.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 com.itdjx.spring.annotation.Main.main(Main.java:15)
    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 'com.itdjx.spring.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 'com.itdjx.spring.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 'com.itdjx.spring.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

    解决方法:

     1 package com.itdjx.spring.annotation.repository;
     2 
     3 import com.itdjx.spring.annotation.TestObject;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Repository;
     6 
     7 /**
     8  * @author Wáng Chéng Dá
     9  * @create 2017-03-03 9:24
    10  */
    11 @Repository("userRepository")
    12 public class UserRepositoryImpl implements UserRepository {
    13 
    14     @Autowired(required = false)
    15     private TestObject testObject;
    16 
    17     @Override
    18     public void sava() {
    19         System.out.println("I am UserRepositoryImpl's sava method...");
    20         System.out.println(testObject);
    21     }
    22 }

    控制台输出:

    I am UserController's execute method...
    I am UserService's add method...
    I am UserRepositoryImpl's sava method...
    null

    使用 @Resource 或 @Inject 自动装配 Bean:

    Spring 还支持 @Resource 和 @Inject 注解 , 这两个注解和 @Autowired 注解的功能类似。

    @Resource 注解要求提供一个 bean 名称的属性 , 若该属性为空 , 则自动采用标注出的变量或方法名作为 bean 的名称。

    @Inject 和 @Autowired 注解一样也是按类型匹配注入的 bean , 但没有 required 属性。

    建议使用 @Autowired 注解。

  • 相关阅读:
    pair
    非整除集合
    集合 set
    实现字通配符*
    vector
    矩阵及其初等变换
    求数组中连续子数组(最少有一个元素)的最大和。
    最长上升序列(Lis)
    st表求区间最大值
    [Noip2015] 信息传递
  • 原文地址:https://www.cnblogs.com/chinda/p/6496826.html
Copyright © 2011-2022 走看看