Bootstrap

Spring注解开发

四、注解

(1).使用注解定义bean
  • 1.注解方式
    • a.使用@Component在Dao、Service等层进行设定

      • @Repository==》数据层bean

      //@Component("bookDao")
      @Repository("bookDao")
      public class BookDao {...}
      • @Service==》业务层bean

      //@Component("bookDao")
      @Service("bookService")
      public class BookServiceImpl implements BookService {...}
      • @Controller==》控制器层

      //@Component("bookDao")
      @Controller
      public class BookController {...}
      • b.在配置文件中新开启一个命名空间,具体步骤如数据源管理所示,并使用context:component-scan 进行扫描注解所设定的单个或多个(使用,分割)类路径

    //单个
      <context:component-scan base-package="Dao"></context:component-scan>
    //多个
      <context:component-scan base-package="Dao,Service"></context:component-scan>
    • c.在业务层进行业务逻辑处理

    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
    BookDao bookDao = (BookDao) ctx.getBean("bookDao");
    System.out.println(bookDao);
    BookServiceImpl bookService = (BookServiceImpl) ctx.getBean("bookService");
    System.out.println("---------------");
    System.out.println(bookService);
    • 使用纯注解进行定义

      • 使用@Configuration指定该类为配置类,@ComponentScan()进行bean指定类路径的扫描

    @Configuration
    @ComponentScan({"Dao","Service"})
    public class SpringConfig {...}
    • ※※※采取纯注解方式定义bean时读取Spring核心配置文件初始化容器对象变成了读取Java配置类初始化容器对象

    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
  • 2.bean的作用范围
    • 在类的声明上方使用@Scope进行注解,参数为singleton(默认单例)/prototype(多例)

    @Repository
    @Scope("singleton")
    public class BookDao {...}
  • 3.bean的生命周期
    • 使用@PostConstructor在自定义初始化方法上进行注解,会在bean的构造方法后执行

    @PostConstruct
    public void init(){
        System.out.println("init...");
    }
    • 使用@PreDestroy在自定义销毁方法上进行注解,会在IoC容器关闭前执行

    @PreDestroy
    public void destroy(){
        System.out.println("destroy...");
    }
(2)注解开发依赖注入
  • 1.引用类型自动装配
    • a.使用@Autowired或则配置文件进行依赖注入前报错NullPointerException==》注入失败

    • b.使用@Autowired进行依赖注入

    @Autowired
    private BookDao bookDao;
    • c.问题:如果出现多个同样类型的bean,会根据名称自动装配,如果bean命名一致,会报出错误NoUniqueBeanDefinitionException,使用@Qualifier和@Repository指定所需的bean进行注入,@qualifier必须和@Autowired配合使用

    @Autowired
    @Qualifier("bookDao")
    private BookDao bookDao;
    ​
    @Repository("bookDao")
    public class BookDaoImpl implements BookDao{
        public void save() {System.out.println("book Dao...");}
    }
    @Repository("bookDao2")
    public class BookDaoImpl2 implements BookDao{{
        public void save() {System.out.println("book Dao...22222222");}
    }
  • 2.基本类型自动装配
    • a.使用@Value进行装配

    @Value("基本类型的自动装配@Value")
    private String name;
    • b.从外部文件对基本类型进行自动装配

      • 使用@PropertySource在SpringConfig文件中加载外部文件

      @PropertySource("myProperties.properties")
      • 使用@Value("${}")进行获取外部文件中对应的值

      @Value("${name}")
      private String name;
      • ※※※注意:在使用@PropertySource()指定文件名时,不可像使用配置文件时location中的所有文件即不可使用*.properties

  • 3.使用注解管理第三方bean
    • a.实现思路==》不推荐使用

      • 编写一个方法用于获取待管理第三方bean,并且该方法使用@Bean注解进行设定==工厂模式

      public DataSource druidDataSource(){
      DruidDataSource dataSource = new DruidDataSource();
          //DataSource接口无set方法
          dataSource.setDriverClassName("com.mysql.jdbc.driver");
          dataSource.setUrl("jdbc:mysql://localhost:3306/spring_db");
          dataSource.setUsername("root");
          dataSource.setPassword("root");
          return dataSource;
      }
      • 使用@Bean==》表示当前方法返回值为bean对象

      @Bean
      public DataSource druidDataSource(){...}
      • 获取并操作bean

      DataSource dataSource = ctx.getBean(DataSource.class);
      System.out.println(dataSource);
    • b.优化方式一(扫描式):抽离+扫描==》不推荐使用

      • 1.将其所编写的方法抽离出来,单独成为一个配置类,与其spring的配置类进行区分

      @Configuration
      public class JdbcConfig {
          @Bean
          public DataSource druidDataSource(){
              return new DruidDataSource();
          }
      }
      • 在Spring的配置类中使用@ComponentScan扫描该配置类

      @ComponentScan("config")
    • c.优化方式二(导入式):抽离+导入==》推荐使用

      • 同优化方式一.1

      • 在Spring的配置类中使用@Import导入该配置类

      @Import(JdbcConfig.class)
  • 4.从外部文件获取资源为第三方bean注入
    • a.定义外部文件

    jdbc.driver = com.mysql.jdbc.drive
    jdbc.url = jdbc:mysql://localhost:3306/spring_db
    jdbc.username = root
    jdbc.password = root
    • b.在spring配置类中使用@PropertySource加载外部文件资源

    @PropertySource("jdbc.properties")
    • c.在jdbc的配置类中使用${}读取资源

    dataSource.setDriverClassName("${jdbc.driver}");
    dataSource.setUrl("${jdbc.url}");
    dataSource.setUsername("${jdbc.username}");
    dataSource.setPassword("${jdbc.password}");
  • 5.配置开发和注解开发的比较
;