Spring – 通过注解配置Bean(8)

  • 2020 年 3 月 17 日
  • 筆記

扫描组件

Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件。

特定组件包括: Component:基本注解,标识了一个受Spring管理的组件 Respository:标识持久层组件 Service: 标识服务层(业务层)组件 Controller:标识表现层组件

对于扫描到组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写;

注解中通过value属性值标识组件的名称

使用注解后,还需要在Spring的配置文件中声明<context:component-scar>: base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有的类;当需要扫描多个包时,可以使用逗号隔开 resource-pattern 扫描特定的类而非基包下的所有类

目录结构

// UserRepository  public interface UserRepository {      void save();  }
// UserRepositoryImpl  @Repository("userRepository")  public class UserRepositoryImpl implements UserRepository {      @Override      public void save() {          System.out.println("UserRepository Save...");      }  }
// UserController  @Controller  public class UserController {        public void execute(){          System.out.println("UserController execute... ");      }  }
// UserService  @Service  public class UserService {      public void add(){          System.out.println("UserService add......");      }  }
// TestObject  @Component  public class TestObject {  }
// Main  public class Main {      public static void main(String[] args) {          ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");          TestObject to = (TestObject)ctx.getBean("testObject");          System.out.println(to);          UserController tuserController = (UserController)ctx.getBean("userController");          System.out.println(tuserController);          UserService userService = (UserService)ctx.getBean("userService");          System.out.println(userService);          UserRepository userRepository = (UserRepository)ctx.getBean("userRepository");          System.out.println(userRepository);      }  }
// xml  <!--指定Spring IOC容器扫描的包 -->  <context:component-scan base-package="com.sangyu.test05.annotation"/>  // resource-pattern 指定扫描的资源  <context:component-scan base-package="com.sangyu.test05.annotation" resource-pattern="repository/*.class"/>

<context:include-filter>: 子节点表示要包含的目标类 <context:exclude-filter>: 子节点表示要排除在外的目标类 <context:component-scar>: 下可以拥有若干个 <context:include-filter><context:exclude-filter>子节点

类别

示例

说明

annotation

com.test.XxxAnntation

所有标注了XxxAnnotation的类。该类型采用目标类是否标注了某个注解进行过滤

assinable

com.test.XxxService

所有继承或扩展XxxService的类,该类型采用目标类是否继承或扩展某个特定类进行过滤

<!--type="annotation" 该类型采用目标类是否标注了某个注解进行过滤-->  <!--context:exclude-filter 子节点指定排除哪些指定表达式的组件-->  <context:component-scan base-package="com.sangyu.test05.annotation">          <context:exclude-filter expression="org.springframework.stereotype.Repository" type="annotation"/>  </context:component-scan>    <!--context:include-filter 子节点指定包含哪些表达式的组件,该子节点需要use-default-filters配合使用-->  <context:component-scan          base-package="com.sangyu.test05.annotation"          use-default-filters="false">          <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>  </context:component-scan>    <!--type="assignable" 所有继承或扩展XxxService的类,该类型采用目标类是否继承或扩展某个特定类进行过滤 -->  <context:component-scan base-package="com.sangyu.test05.annotation">      <context:exclude-filter type="assignable" expression="com.sangyu.test05.annotation.repository.UserRepository"/>  </context:component-scan>    <context:component-scan base-package="com.sangyu.test05.annotation" use-default-filters="false">      <context:include-filter type="assignable" expression="com.sangyu.test05.annotation.repository.UserRepository"/>  </context:component-scan>

使用@Autowired自动装配Bean

构造器,普通字段(即使是非public)一切具有参数的方法都可以应用@Autowired注解

默认情况下,所有使用@Autowired注解的属性都需要被设置,当Spring找不到匹配的Bean装配属性时,会抛出异常

// UserService  @Service  public class UserService {      @Autowired      private UserRepository userRepository;      public void add() {          System.out.println("UserService add......");          userRepository.save();      }  }  // 另一种方式  @Service  public class UserService {      private UserRepository userRepository;      @Autowired      public void setUserRepository(UserRepository userRepository){          this.userRepository = userRepository;      }      public void add() {          System.out.println("UserService add......");          userRepository.save();      }  }
// UserController  @Controller  public class UserController {      @Autowired      private UserService userService;      public void execute() {          System.out.println("UserController execute... ");          userService.add();      }  }
// Main  public class Main {      public static void main(String[] args) {          ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");          UserController userController = (UserController) ctx.getBean("userController");          System.out.println(userController);          userController.execute();      }  }

若某一属性允许不被设置,可以设置@Autowired注解的required属性为false

// Main  public class Main {      public static void main(String[] args) {          ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");          UserRepository userRepository = (UserRepository)ctx.getBean("userRepository");          System.out.println(userRepository);      }  }
// TestObject  //@Component 注释掉  public class TestObject { }
// 实现类  @Repository("userRepository")  public class UserRepositoryImpl implements UserRepository {      @Autowired(required = false)      private TestObject testObject;      @Override      public void save() {          System.out.println("UserRepository Save...");          System.out.println(testObject);      }  }  // 接口  public interface UserRepository {      void save();  }

两个类实现一个接口的情况

// 接口  public interface UserRepository {      void save();  }    // 实现类1  @Repository("userRepository") // 两个类实现一个接口 ,默认会按照设置的名字去查找实现类  public class UserRepositoryImpl implements UserRepository {      @Autowired(required = false)      private TestObject testObject;      @Override      public void save() {          System.out.println("UserRepository Save...");          System.out.println(testObject);      }  }    // 实现类2  @Repository  public class UserJdbcRepository implements UserRepository {      @Override      public void save() {          System.out.println("UserJdbcRepository save....");      }  }  // Main  public class Main {      public static void main(String[] args) {          ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");          UserService userService = (UserService)ctx.getBean("userService");          System.out.println(userService);          userService.add();      }  }
// 另一种方式:使用@Qualifier  @Service  public class UserService {      @Autowired      @Qualifier("userJdbcRepository")      private UserRepository userRepository;      public void add() {          System.out.println("UserService add......");          userRepository.save();      }  }