在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 类就可以了。
运行结果如下: