15个Spring的核心注释示例

众所周知,Spring DI和Spring IOC是Spring Framework的核心概念。让我们从org.springframework.beans.factory.annotation和org.springframework.context.annotation包中探索一些Spring核心注解。我们经常将这些称为“Spring核心注解”,我们将在本文中对它们进行讲解。

这是所有已知的Spring核心注解的列表。

@Autowired

我们可以使用@Autowired注释来标记Spring将要解析和注入的依赖关系。我们可以将这个注释与构造函数,setter或字段注入一起使用。

构造器注入

@RestController

public class CustomerController

{

private CustomerService customerService;

@Autowired

public CustomerController ( CustomerService customerService)

{  

this. customerService = customerService;

}}

setter注入

import org. springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class CustomerController

{

private CustomerService customerService;

@Autowired

public void setCustomerService(CustomerService = customerService)

{  

this.customerService=customerService;

}}

领域注入

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class CustomerController

{

@Autowired private CustomerService = customerService;

}

@Bean

@Bean是方法级注释,是XML元素的直接模拟。 注释支持一些提供的属性,例如init-method,destroy-method,auto-wiring和name。

您可以在 @Configuration注解或 @Component注解类中使用 @Bean批注

以下是

方法声明的简单示例:

上述配置等效于以下Spring XML:

<beans>  

<beanid="customerS ervice"class="com.companyname.projectname.CustomerService“/>

<beanid="orderService"clas”="com.companyname.projectname.OrderService"/>

</beans>importorg.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import com.companyname.projectname.customer.CustomerService;

import com.companyname.projectname.order.OrderService;

@Configuration

public class Application

{

@Bean

public CustomerService customerService()

{  

return new CustomerService();

}

@Bean

public OrderService orderService();

{  

return new OrderService();

}}

@Bean

@Qualifier

此注释有助于微调基于注释的自动布线。 可能存在这样的情况:我们创建多个相同类型的bean,并且只想使用属性连接其中一个bean。 这可以使用@ Qualifier注释以及 @Autowired注释来控制。

示例:考虑使用EmailService和SMSService类来实现单个MessageService接口

为多个消息服务实现创建MessageService接口。

public interface MessageService

{

public void sendMsg(String message);

}

接下来,创建实现:EmailService和SMSService。

public class SMSService implements MessageService

{

public void sendMsg(Stringmessage)

{  

System.out.println(message);

}

}

public class EmailService implements MessageService

{

public void sendMsg(Stringmessage)

{  

System.out.println(message);

}

}

这时候该看看 @Qualifier注释的用法了

public interface MessageProcessor

{

public void processMsg(String message);

}

public class MessageProcessorImpl implements MessageProcessor

{

private MessageService messageService;

// setter based DI

@Autowired

@Qualifier("emailService")

public void setMessageService(MessageService messageService)

{

this.messageService=messageService;

}

// constructor based DI

@Autowired

public MessageProcessorImpl(@Qualifier("emailService")MessageService=messageServic)

{  

this.messageService=messageService;

}

public void processMsg (String message)

{

messageService.sendMsg(message);

}

}

@Required

@Required 注释是一个方法级注释,并应用于bean的setter方法。此注释仅指示必须将setter方法配置为在配置时使用值依赖注入。例如,对setter方法的 @Required标记了我们想要通过XML填充的依赖项:

@Required

void setColor(Stringcolor){

this.color =color;

}

<bean class="com.javaguides.spring.Car">    

<property name="color"value="green"/>

</bean>

否则,将抛出BeanInitializationException。

@Value

Spring @Value 注释用于为变量和方法参数指定默认值。我们可以使用@Value 注释来读取Spring环境变量以及系统变量 。Spring @Value 注释也支持SpEL。让我们看一下使用@Value 注释的一些示例 。 

示例:我们可以使用@Value 注释为类属性指定默认值 。

@Value

("Default DBConfiguration")    

private String defaultName;

该 @Value 注释参数可以是只有字符串,但春天尝试将其转换为指定的类型。以下代码将正常工作,并将布尔值和整数值分配给变量。

@Value("true")    

private boolean defaultBoolean;

@Value("10")

   private int defaultInt;

这演示了Spring @Value - Spring环境变量

@Value("${APP_NAME_NOT_FOUND}")  

private String defaultAppName;

接下来,使用 @Value 注释分配系统变量 。

@Value("${java.home}")    

private String javaHome;    

@Value("${HOME}")

   private String homeDir;

Spring @Value – SpEL

@Value("#{systemProperties['java.home']}")

   privatem String javaHome;

@DependsOn

该 @DependsOn 注释可以强制的Spring IoC容器中的bean,它是由注释之前初始化一个或多个bean @DependsOn 注释。

所述 @DependsOn 注释可以在直接或间接地注释与任何类使用 @Component 或与所述注解的方法 @Bean。

示例:让我们创建 FirstBean 和 SecondBean 类。在此示例中, SecondBean 在 bean之前初始化 FirstBean。

public class FirstBean{    

@Autowired    

private SecondBean secondBean;

}

public class SecondBean {

public  SecondBean() {

       System.out.println("SecondBean Initialized via Constuctor");

   }

}

基于配置类在Java中声明上述bean。

@Configuration

public class AppConfig {

   @Bean("firstBean")

   @DependsOn(value = {

       "secondBean"

   })

   public FirstBean firstBean() {

       return new FirstBean();

   }

   @Bean("secondBean")

   public SecondBean secondBean() {

       return new SecondBean();

   }

}

@Lazy

默认情况下,Spring IoC容器在应用程序启动时创建并初始化所有单例bean。我们可以通过使用 @Lazy 注释来防止单例bean的这种预初始化 。所述 @Lazy 注释可以在任何类中使用,与直接或间接地注释 @Component 或与所述注解的方法 @Bean。

示例:考虑我们有两个bean - FirstBean 和 SecondBean。在此示例中,我们将FirstBean 使用 @Lazy注释显式加载。

public class FirstBean {

   public void test() {

       System.out.println("Method of FirstBean Class");

   }

}

public class SecondBean {

   public void test() {

       System.out.println("Method of SecondBean Class");

   }

}

基于配置类在Java中声明上述bean。

@Configuration

public class AppConfig {

   @Lazy(value = true)

   @Bean

   public FirstBean firstBean() {

       return new FirstBean();

   }

   @Bean

   public SecondBean secondBean() {

       return new SecondBean();

   }

}

我们可以看到,bean secondBean 由Spring容器初始化,而bean firstBean 则被显式初始化。

@Lookup

注释的方法 @Lookup 告诉Spring在我们调用它时返回方法返回类型的实例。

@Primary

我们使用 @Primary 当存在多个相同类型的bean时,我们使用它 给bean更高的优先级。

@Component

@Primary

class Car implements Vehicle {}

@Component

class Bike implements Vehicle {}

@Component

class Driver {

   @Autowired

   Vehicle vehicle;

}

@Component

class Biker {

   @Autowired

   @Qualifier("bike")

   Vehicle vehicle;

}

@Scope

我们使用@ Scope注释来定义 @Component类的范围或 @Bean定义。 它可以是单例,原型,请求,会话,globalSession或某些自定义范围。

举个例子:

@Component

@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)

public class TwitterMessageService implements MessageService {

}

@Component

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

public class TwitterMessageService implements MessageService {

}

@Profile

如果我们希望Spring仅在特定配置文件处于活动状态时使用@Component类或@Bean方法,我们可以使用@Profile标记它。 我们可以使用注释的value参数配置配置文件的名称:

@Component

@Profile("sportDay")

class Bike implements Vehicle {}

@Import

该 @Import 注释指示一个或多个 @Configuration类进口。

例如:在基于Java的配置中,Spring提供了 @Import注释,允许从另一个配置类加载 @Bean定义。

@Configuration

public class ConfigA {

   @Bean

   public A a() {

       return new A();

   }

}

@Configuration

@Import(ConfigA.class)

public class ConfigB {

   @Bean

   public B b() {

       return new B();

   }

}

现在,在实例化上下文时,不需要同时指定ConfigA类和ConfigB类,只需要显式提供ConfigB。

@ImportResource

Spring提供了一个@ImportResource注释,用于将applicationContext.xml文件中的bean加载到ApplicationContext中。 例如:考虑我们在类路径上有applicationContext.xmlSpring bean配置XML文件。

@Configuration

@ImportResource({"classpath*:applicationContext.xml"})

public class XmlConfiguration {

}

@PropertySource

该 @PropertySource 注释提供了一种方便的声明性机制,用于添加 PropertySource Spring的Eenvironment以与@Configuration类一起使用 。

例如,我们从文件config.properties文件中读取数据库配置,并使用Environment 将这些属性值设置为 DataSourceConfig类。

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.PropertySource;

import org.springframework.core.env.Environment;

@Configuration

@PropertySource("classpath:config.properties")

public class ProperySourceDemo implements InitializingBean {

   @Autowired

   Environment env;

   @Override

   public void afterPropertiesSet() throws Exception {

       setDatabaseConfig();

   }

   private void setDatabaseConfig() {

       DataSourceConfig config = new DataSourceConfig();

       config.setDriver(env.getProperty("jdbc.driver"));

       config.setUrl(env.getProperty("jdbc.url"));

       config.setUsername(env.getProperty("jdbc.username"));

       config.setPassword(env.getProperty("jdbc.password"));

       System.out.println(config.toString());

   }

}

@PropertySources

我们可以使用此批注指定多个@PropertySource配置:

@PropertySources({

 @PropertySource("classpath:config.properties"),

 @PropertySource("classpath:db.properties")

})

public class AppConfig {

 //...

}

欢迎工作一到五年的Java工程师朋友们加入Java程序员开发: 854393687

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容