@Component 元注解
@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分
@Component 元注解的更多相关文章
- Spring Boot实战笔记(九)-- Spring高级话题(组合注解与元注解)
一.组合注解与元注解 从Spring 2开始,为了响应JDK 1.5推出的注解功能,Spring开始大量加入注解来替代xml配置.Spring的注解主要用来配置注入Bean,切面相关配置(@Trans ...
- Spring注解与Java元注解小结
注解 Annotation 基于注解的开发,使得代码简洁,可读性高,简化的配置的同时也提高了开发的效率,尤其是SpringBoot的兴起,随着起步依赖和自动配置的完善,更是将基于注解的开发推到了新的高 ...
- 曹工说Spring Boot源码(23)-- ASM又立功了,Spring原来是这么递归获取注解的元注解的
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- spring源码解析:元注解功能的实现
前言 众所周知,spring 从 2.5 版本以后开始支持使用注解代替繁琐的 xml 配置,到了 springboot 更是全面拥抱了注解式配置.平时在使用的时候,点开一些常见的等注解,会发现往往在一 ...
- Java 元注解
元注解@Target,@Retention,@Documented,@Inherited * * @Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: * Elemen ...
- Java元注解
元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种. 1.@Retention: 定义注解的保留策略@Retention(RetentionP ...
- [读书笔记] 二、条件注解@Conditional,组合注解,元注解
一.条件注解@Conditional,组合注解,元注解 1. @Conditional:满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的. 例子: 首先,两个Condi ...
- 自定义注解,andjdk提供的元注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FruitN ...
- Java开发笔记(八十二)注解的基本单元——元注解
Java的注解非但是一种标记,还是一种特殊的类型,并且拥有专门的类型定义.前面介绍的五种内置注解,都可以找到对应的类型定义代码,例如查看注解@Override的源码,发现它的代码定义是下面这样的: @ ...
随机推荐
- linux 挂载硬盘 + 对硬盘 分区
parted命令可以划分单个分区大于2T的GPT格式的分区,也可以划分普通的MBR分区 fdisk命令对于大于2T的分区无法划分,所以用fdisk无法看到parted划分的GPT格式的分区 1. 用 ...
- C++面向对象高级开发课程(第二周)
1. 类中含有指针—— class with pointer member(s) ——的情况经常发生,典型的有:string 类. 2. STL中的 string 类太复杂,copy on write ...
- centos+Jenkins+maven搭建持续集成
Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能 什么是持续集成 随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成 ...
- tensorflow 生成随机数 tf.random_normal 和 tf.random_uniform 和 tf.truncated_normal 和 tf.random_shuffle
____tz_zs tf.random_normal 从正态分布中输出随机值. . <span style="font-size:16px;">random_norma ...
- 一款简单实用的jQuery图片画廊插件
图片画廊 今天分享一个自己实现的jQuery 图片画廊插件. 看一下效果图: 点击图片时: 在线演示地址:http://www.jr93.top/photoGallery/photoGallery.h ...
- 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 1 章 答案
判断对错1.计算机科学是计算机的研究.2.CPU 是计算机的“大脑”.3.辅助存储器也称为 RAM.4.计算机当前正在处理的所有信息都存储在主存储器中.5.语言的语法是它的意思,语义是它的形式.6.函 ...
- 断开网络连接的dos命令
https://zhidao.baidu.com/question/154994771.html 或者采用服务关闭开启模式,不过没有上面的好用net stop "network connec ...
- redis持久化RDB和AOF-转载
Redis 持久化: 提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF. RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AO ...
- Elasticsearch工作原理
一.关于搜索引擎 各位知道,搜索程序一般由索引链及搜索组件组成. 索引链功能的实现需要按照几个独立的步骤依次完成:检索原始内容.根据原始内容来创建对应的文档.对创建的文档进行索引. 搜索组件用于接收用 ...
- 编译安装lamp (php)
用户账号及权限管理 用户账号:'user'@'host' user: 用户名 host: 此用户访问mysqld服务时允许通过哪些主机远程创建连接: host类型:IP.网络地址.主机名.通配符(%和 ...