spring之注解(三)Component

上篇文章中比较详细的介绍了依赖注入的相关注解,尤其是@Autowired。但是我们对bean的定义声明还是放在xml的配置文件中。Spring当然提供了机制可以自动的扫描类路径,自动的向容器注册BeanDefinition。这就是Bean级别的注解。以上机制称为类路径扫描(clsspath-sacn),它是有相关注解(如@Component @Named @Bean)和beanFactoryPostProcessor和BeanPostProcessor实现的。本篇文章我们依次对各个注解进行说明。

本篇使用的示例代码继承之前的篇章。首先看注解。

@Component

元注解

这是一个元注解,意思是它可以用于标注其他注解,被它标注的注解和它起到相同或者类似的作用。Spring用它定义了其他具有特定意义的注解如@Controller @Service @Repository。如下是Spring中 @Service的定义:

@Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component // Spring will see this and treat @Service in the same way as @Component
    public @interface Service {
    }

另外@Controller  和 @Repository与之类似。Spring在web项目赋予这些注解特殊的含义。分别表示控制器和 数据访问层。

自定义

我们可以自定义注解,如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface MyComponent {
String value();
}

使用

我们现在可以使用(自定义)注解直接标注在某个类上,此类就会自动的被Spring容器注册为BeanDefinition,我们可以对上篇文章中在xml中定义的bean改也注解的方式进行声明:

//使用元注解
@Component("user1")
public class UserServiceIml1 implements UserService{

    private UserDao userDao;
    @Override
    public List<User> getUser() {
       return userDao.getUser();
    }
    //标注在set方法上。
    @Autowired
    public void setUserDao(@Qualifier("userDao") UserDao userDao) {
       this.userDao = userDao;
    }
}
//使用自定义注解
@MyComponent("user2")
public class UserServiceIml2 implements UserService{
    //标注在字段上。
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao;
    @Override
    public List<User> getUser() {
       return userDao.getUser();
    }

}

以上使用注解后,我们需要做一些配置是Spring启用类路径扫描(classpath-scan),在XML配置中加入以下配置,这个配置就自动启用了注解的相关功能:

 <context:component-scan base-package="com.test"/>

以上注解表示自动扫描com.test包及其子包下被@component(或者其扩展)表中的类,并把他们注册为bean。以上配置还有其他属性,可以定义专门的过滤器做自定义的配置。

以下为一个示例:

<context:component-scan base-package="org.example">
        <context:include-filter type="regex"
                expression=".*Stub.*Repository"/>
        <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>

@Bean

在采用XML配置bean的时候,我们可以使用实例工厂来定义一个Bean,采用@Bean注解我们也可以做到类似的形式。在一个Bean中定义另外一个Bean。这通过在@Component的标注类中对某个方法使用@Bean进行注解。

如下所示:

@Bean(name="getService")
   @Qualifier("getService")
   public UserService getService(@Qualifier("userDao") UserDao user){
      UserService ser = new UserServiceIml1();

      return ser;
   }

上述定义一个Bean,并定义了Name和Qualifier属性。还可以定义Scope,Lazy等属性。见下个小节。

其实@Bean更多的是与@Confuguration一起使用,来构建另外一种不同于基于XML的ApplicationContext,即基于注解的,AnnotationConfigApplicationContext。这个以后讨论。

命名和其他属性

命名

基于@Componet及其扩展(如@Servic和自定义等)标注和classpath-scan定义的Bean,注解有一个value属性,如果提供了,那么就此Bean的名字。如果不提供。就会使用Spring默认的命名机制,即简单类名且第一个字母小写,见如下示例:

@Component("user5")
//Bean的名称是user5
public class UserServiceIml5 implements UserService{
}

@Component()
//Bean的名称是userServiceIml3
public class UserServiceIml3 implements UserService{
}

我们可以更新Spring默认的命名机制,只要我们实现了相关接口BeanNameGenerator,并进行配置,如下:

<context:component-scan base-package="org.example"
        name-generator="org.example.MyNameGenerator" />

其他

在基于XML的配置中bean标签还有很多属性,如scope、Lazy、init-method、depends-on、Qualifier等。下面通过一个简单的配置例子说明:

package com.test.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

import com.test.bo.User;
import com.test.dao.UserDao;
import com.test.dao.UserDaoImp;
import com.test.service.UserService;
//使用元注解
@Component("user1")
@Qualifier("user1")
@Lazy(true)
@DependsOn("userDao")
public class UserServiceIml1 implements UserService{

   private UserDao userDao;
   @Override
   public List<User> getUser() {

      return userDao.getUser();
   }
   //标注在set方法上。
   @Autowired
   public void setUserDao(@Qualifier("userDao") UserDao userDao) {
      this.userDao = userDao;
   }

   @Bean(name="getService",initMethod="init1",destroyMethod="close1")
   @Qualifier("getService")
   @Scope(value="singleton")
   @Lazy(true)
   @DependsOn("getDao")
   public UserService getService(@Qualifier("getDao") UserDao user){
      System.out.println("------------getService is creted when used--------------");
      System.out.println(user.getClass().toString());
      UserService ser = new UserServiceIml1();
      return ser;
   }

   @Bean(name = "getDao")
   @Qualifier("getDao")
   @Scope(value="prototype",proxyMode=ScopedProxyMode.TARGET_CLASS)
   @Lazy(true)
   public UserDao getDao(){
      System.out.println("------------getDao is creted when used--------------");
      return new UserDaoImp();
   }

   private void init1(){
      System.out.println("---------getService init1----------------");

   }

   private void close1(){
      System.out.println("---------getService close----------------");
   }
   public UserDao getUserDao() {
      return userDao;
   }

}

上述分别在类上和某个方法上,加入了很多的属性配置,可以和传统的XMl的配置比较。主要singleton引用其他类型时,需要生成代理。

@Configuration

Spring提供一种基于注解的applicationContext,实际应用中,它可以和XML的配置联合使用或者各自单独使用。当使用时,需要很大的利用的@Bean注解。

下面给一个简单的例子,其他的详细例子见Spring官方文档。

首先是一个@Configuration 的配置类,定义了两个Bean。

@Configuration
public class MyAnnoConfig {

   @Bean(name="cDao1")
   public UserDao getConfigDao(){
      return new UserDaoImp();
   }

   @Bean(name="cs1")
   public UserService getConfigS(@Qualifier("cDao1") UserDao dao){

      UserServiceIml us =new UserServiceIml();
      us.setUserDao(dao);
      return us;
   }

}

下面是测试函数。

public class TestAnnoContextMain {

   public static void main(String[] args) {
      ApplicationContext  ctx = new AnnotationConfigApplicationContext(MyAnnoConfig.class);

      UserService us = ctx.getBean("cs1",UserService.class);
      System.out.println(us.getUser());
   }
}

总结

本篇较详细的说明了Spring支持的Bean级别的注解的使用方法,主要介绍了@Component和@Bean(在@component中使用),并穿插介绍了一些Bean属性的注解。最后注意举例说明Spring的基于注解的applicationContext和@configuration。

注意,本篇没有介绍JSR-330的注解@Named,其和@Component基本一致,但不如前者强大。并且我认为只要比较清楚的一种方式的原理和使用方法,其他的都是举一反三的例子=,这也是不详细写@configuration的原因(其实它和@Bean配合,和基于XML的配置的功能几乎一样)。本完整测试代码0分

时间: 2024-10-10 00:17:04

spring之注解(三)Component的相关文章

Spring JSR-250注解

Spring JSR-250注解 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名.类型等信息,如果关系表字段和 PO 属性名.类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取. 注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果

关于Spring注解 @Service @Component @Controller @Repository 用法

@Component 相当于实例化类的对象,其他三个注解可以理解为@Component的子注解或细化. 在annotaion配置注解中用@Component来表示一个通用注释用于说明一个类是一个spring容器管理的类,此类将有spring扫描并加入容器参与ioc.即就是该类已经拉入到spring的管理中了. 通过在 classpath 中通过自动扫描方式把组建纳入 spring 容器管理. 要使用自动扫描机制我们需要打开一下配置信息: Bean.xml代码    <?xml version= 

spring注解中@component是什么意思

@Component("userManager") public class UserManagerImpl implements UserManager { private UserDao userDao; public UserDao getUserDao() { return userDao; } @Resource public void setUserDao(UserDao userDao) { this.userDao = userDao; } /* * (non-Java

Spring Data 系列(三) Spring+JPA(spring-data-commons)

本章是Spring Data系列的第三篇.系列文章,重点不是讲解JPA语法,所以跑开了JPA的很多语法等,重点放在环境搭建,通过对比方式,快速体会Spring 对JPA的强大功能. 准备代码过程中,保持了每个例子的独立性,和简单性,准备的源码包,下载即可使用.如果,对JPA语法想深入研究的话,直接下载在此基础上进行测试. 前言 Spring Data 系列(一) 入门:简单介绍了原生态的SQL使用,以及JdbcTemplate的使用,在这里写SQL的活还需要自己准备. Spring Data 系

Spring常用注解总结

传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件,那么.xml文件又会非常多.总之这将导致配置文件的可读性与可维护性变得很低.2.在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率.为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密

atititt.java定时任务框架选型Spring Quartz 注解总结

atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz  (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增加context,task命名空间xml: 2 2.2. 增加xsi:schemaLocation valide 2 2.3. 我们的task任务扫描注解in spr.xml 2 2.4. 设置运行方法 3 2.5. 设置输出日志 3 3. 运行测试sprX走ok兰. 4 4. Quartz Sch

spring之注解(一)概述

Spring的核心是依赖注入(DI),而依赖注入的基础是依赖信息的配置.这些配置称之为元数据. 在之前的的学习中.一直採用的是基于xml的配置,这些元数据配置在spring内部被注冊成为BeanDefinition,spring以此为模版创建bean和注入依赖. 从spring 2.0開始,spring依次增加了对注解型元数据配置的支持.自此我们有了第二种配置bean的方式.Spring包括非常多种注解,如我们比較熟悉的@AutoWired.@Compoent,另一些不太熟悉的如@Inject

Spring AOP 注解配置实例

Spring AOP注解例子 一:导入相关jar包. 首先导入Spring的相关包(这里就不多说了,我这里是3.2.4版本的) 然后导入AOP注解的相关包(不是spring的包)aspectjrt-1.6.7.jar和aspectjweaver-1.6.8.jar和aopalliance.jar (注意这里最好是1.6.7以上的版本,不然容易出错,折腾了我好久,最后才发现是包的版本问题. 所以这里一定要注意,spring 2.0以后的最好是用1.6.7的版本) 二: 建一个class类作为切入面

spring - 自定义注解

本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用. java内置注解 1.@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: ElemenetType.CONSTRUCTOR   构造器声明 ElemenetType.FIELD   域声明(包括 enum 实例) ElemenetType.LOCAL_VARIABLE   局部变量声明 ElemenetType.METHOD   方法声明 ElemenetType.PACKAGE   包声明