在Spring中,Bean的配置可以用两种方法实现,第一种是基于XML配置文件,第二种就是本文要阐述的基于JAVA代码配置,而这种配置又是通过注解来实现的,所以本文先简要总结一下注解,然后再阐述基于JAVA代码的Bean配置。
1、注解
在JAVA中注解其实就是嵌套在JAVA 代码中的元信息,起到辅助和配置的作用,它并不会改变代码的逻辑。
注解以可分为元注解和复合注解,在JAVA中元注解主要有以下几种: @Target、@Retention、@Documented、@Inherited
@Target指定了某个自定义注解可以作用于哪个级别元素,它里面的参数是一个ElementType枚举类型的数组。该枚举类型字段如下:
TYPE(类型),FILED(字段)METHOD(方法)PARAMETER(参数)CONSTRUCTOR(构造器)LOCAL_VARIABLE(局部变量)
ANNITATION_TYPE(注解)PACKAGE(包)其中TYPE是指可以用在class,interface,eumn,annotation上面,如果没有制定,那么它可以用在任何上面
例如使用@Target({ElementType.METHOD})
则该注解只可作用于一个类中的方法上。
@Retention指定的注解的保留策略,有三种类型即SOURCE,CLASS, RUNTIME
SOURCE表示这个Annotation类型的信息只会保留在源码里,源码经过编译之后,Annotation的数据就会消失,并不会保留在编译好的.class文件里;
CLASS表示这个Annotation类型的信息在源码保留,在.class文件也保留,但不会把这些信息加载到虚拟机(JVM)中,如果不设置,系统默认值是CLASS;
RUNTIME表示在源码,编译后的.class都保存信息,在执行的时候也会把这些信息加载到JVM中
@Documented指定注解是否保存在Javadoc中,@Inherited指定注解是否可以被子类继承。
例如我们可以这样来定义一个注解:
package com.ev.annotation; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.ElementType; @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface HelloWorld { public String name()default ""; }
name指定该注解的属性,这里设置的默认值为空字符串。
2、基于JAVA代码的Bean配置
在这之前我们先来创建JAVA代码中的Bean结构
public class Bar { private String name; public Bar(String name) { super(); this.name = name; } public void showBar(){ System.out.println("hello "+name); } }
然后根据这个类做Bean配置
@Configuration public class AppConfig { @Bean("bar") public Bar getBar(){ return new Bar("YKG"); } }
AppConfig 类是一个“配置类”,该类中有一个工厂方法getBar()
,这个方法返回了一个Bean实例。然后在方法中就可以获取该Bean实例,并调用该实例的方法了。
public static void main(String[] args){ ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); Bar bar = (Bar) ctx.getBean("bar"); bar.showBar(); }
这个配置中使用了注解@Configuration、@Bean
。
不过当我们有多个“配置类”时,可以使用@Import
把其它的”配置类“相关的Bean配置信息导入到当前类中,使得我们在某个地方引用时,只需引入当前”配置类“就可以了。
例如:
第一个配置类的信息为
@Configuration @Import(AppConfigB.class) public class AppConfig { @Bean("bar") public Bar getBar(Baz baz){ ba.setName("YKG"); return new Bar(baz); } }
这里通过@Import(AppConfigB.class)
引入了另外一个”配置类“信息。其对应的Bean结构信息为:
public class Bar { private Baz baz; public Bar(Baz baz){ this.baz = baz; } public void showBar(){ baz.showBaz(); } }
第二个配置类为
@Configuration public class AppConfigB { @Bean(name="baz") public Baz getBaz(){ return new Baz(); } }
其对应的Bean结构信息为
public class Baz { private String name = "AAA"; public void showBaz(){ System.out.println("Hello this is "+name+"!!"); } public void setName(String name) { this.name = name; } }
这里我们要注意AppConfig 类中的getBar(Baz baz)
方法参数baz是自动注入进来的,所以我们才可以调用Baz中的实例方法。
这样我们只需在主函数中引用AppConfig 类就可以了。
运行结果如下: