1. 9IM首页
  2. 热点

Spring大神之路(8)–提高资源管理的灵活性(使用JavaConfig定义bean)

注解方式配置bean的局限性

使用注解代替xml配置bean之后,效率得到了显著提升,我们程序员写起代码了也甚是爽快,毕竟相对于编写xml,写代码无疑是更加爽快的。

使用注解定义bean的方式虽然方便快速,灵活性却有所不足,举个最简单的例子,我们使用xml可以生成同一类型的多个bean,例如下面生成了两个Singer类型的bean。

	<bean id="zhoujielun" class="org.maoge.xmlbeandetail.Singer">
		<property name="name" value="周杰伦"></property>
	</bean>
	<bean id="linjunjie" class="org.maoge.xmlbeandetail.Singer">
		<property name="name" value="林俊杰"></property>
	</bean>

但是使用注解时,一个类型下只能生成一个bean,如下:

@Component("zhoujielun")
public class Singer {
}

显然,使用注解后虽然效率提升,但是貌似功能不如xml强大了。

思考如何解决

使用xml,需要额外写xml配置文件,效率低下。

而使用注解,一个注解只能加到一个类上,也就是说一个类只能生成一个bean,功能有所欠缺。

那么如何既能利用注解快速生成多个bean,同时bean还可以自定义其名称(id)和相关属性呢?

哈哈,其实不难,我们可以将注解加到方法上,然后返回值类型作为bean的类型,不就解决问题了。返回同样类型的方法可以定义任意多个,解决了对类使用注解定义bean时不能生成多个bean的问题;同时注解直接加到方法上,也不用再单独定义xml文件描述bean和其类型的关联。可谓:效率提升的同时又兼具灵活性!

三种方式对比

好的,到目前为止,Spring容器中配置bean的三种方式我们都发现了:xml、注解、JavaConfig,我们来对比下:

  • xml功能很强,但是不够方便快速(代码量比较大)
  • 注解非常方便快速,但是功能不够强大(有些bean描述不了)
  • JavaConfig比较方便快速,同时功能也足够强大

注意哈,大家可能普遍比较了解xml和注解方式,反而对比较先进的JavaConfig方式不熟悉,此处原因我认为是这样的:xml产生的比较早,网上相关的文档也比较多,所以大家比较熟悉。注解方式代码量非常精简,而且足以满足大多数场景使用,现在用的也比较多,所以大家比较熟悉;JavaConfig方式虽然足够锋利,但是由于历史等原因,目前还不足够的流行,但是其实它真的棒棒哒,我认为这种方式:真的真的很不错。

最后必须强调一点:三种方式只是方式不同,没有本质区别,都是为Spring容器提供配置信息。大家可以根据实际情况灵活选用,反正我个人是倾向于注解+JavaConfig的方式,为何?因为注解足够简单,而JavaConfig足够灵活,xml确实比较麻烦。

使用JavaConfig定义bean的具体实例

光说不练那是假把式,必须得有实例。但是前提是兄弟们咱已经把事情的来龙去脉说清楚了,要是不知道为何而来从何而去,比较容易混淆概念,从而容易懵圈。

说实话我Spring写了很久了,还搞不清楚这三种方式的区别,后来是靠着我强悍的大脑的超强理解能力才分清楚的(请原谅我无脑的对自己的吹捧,朋友们我就是这么一个人,非常完美吭)。

话不多少,酒不多喝,实例走起!

step1 来个普普通通的类

普普通通,毫无污染的普通Java类一个,供您鉴赏。

package org.maoge.javaconfigbean;
public class Singer {
	private String name;
	public void sing() {
		System.out.println("歌手[" + name + "]开唱啦,快挥舞起你手中的荧光棒吧");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
setup2 来个普普通通的方法返回我们想要的对象

我们定义两个方法,返回我们想要的对象,这两个方法到目前为止是再普通不过的普通方法。

package org.maoge.javaconfigbean;
public class BeanConfiguration {
	/**
	 * 返回歌手周杰伦
	 */
	public Singer zhoujielun() {
		Singer singer = new Singer();
		singer.setName("周杰伦");
		return singer;
	}
	/**
	 * 返回歌手林俊杰
	 */
	public Singer linjunjie() {
		Singer singer = new Singer();
		singer.setName("林俊杰");
		return singer;
	}
}
setup3 添加@bean注解,使方法的返回值成为bean

通过在方法上添加@bean注解,Spring容器会将方法的返回值作为bean放入容器中,而bean的名字就是方法的名字。

package org.maoge.javaconfigbean;
import org.springframework.context.annotation.Bean;
public class BeanConfiguration {
	/**
	 * 返回歌手周杰伦 通过@Bean告知容器,将该方法的返回值作为bean放入容器中管理
	 */
	@Bean
	public Singer zhoujielun() {
		Singer singer = new Singer();
		singer.setName("周杰伦");
		return singer;
	}
	/**
	 * 返回歌手林俊杰 通过@Bean告知容器,将该方法的返回值作为bean放入容器中管理
	 */
	@Bean
	public Singer linjunjie() {
		Singer singer = new Singer();
		singer.setName("林俊杰");
		return singer;
	}
}
setup4 添加@Configuration注解启用配置

在之前讲述使用注解定义bean时,我们有一个xml配置context:component-scan,用来扫描指定的包下面的bean。

在使用JavaConfig定义bean是也类似,我们需要在类上添加注解@Configuration,来告诉Spring,该类是一个配置类,里面可能包含bean的定义,请扫描我。具体代码如下:

package org.maoge.javaconfigbean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 通过@Configuration告诉Spring,本类是一个配置类,请扫描本类中的bean
 */
@Configuration
public class BeanConfiguration {
	/**
	 * 返回歌手周杰伦
	 */
	@Bean
	public Singer zhoujielun() {
		Singer singer = new Singer();
		singer.setName("周杰伦");
		return singer;
	}
	/**
	 * 返回歌手林俊杰
	 */
	@Bean
	public Singer linjunjie() {
		Singer singer = new Singer();
		singer.setName("林俊杰");
		return singer;
	}
}
setup5 测试运行

这一步就很简单了,先通过配置类获取容器对象,然后从容器中获取定义的bean,然后运行bean的方法。

注意AnnotationConfigApplicationContext也好理解,就是Spring给我们封装好的类,它可以读取类中注解的配置信息(此处读取BeanConfiguration.class),然后根据配置信息为我们生成容器,我们直接调用就行。

package org.maoge.javaconfigbean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigContainerDemo {
	public static void main(String[] args) {
		//通过BeanConfiguration.class获取对Spring容器的配置信息,然后返回context指向容器
		AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(BeanConfiguration.class);
		//从容器中获取对象
		Singer zhoujielun=(Singer) context.getBean("zhoujielun");
		zhoujielun.sing();
		//从容器中获取对象
		Singer linjunjie=(Singer) context.getBean("linjunjie");
		linjunjie.sing();
	}
}

总结

Spring提供了三种定义bean的方式,就好比我们生活中出行可以采用高铁、飞机、汽车、自行车、走路一样的道理,更加方便,可以根据实际情况灵活选用。

但是目的相同,都是为了给Spring容器提供配置信息,主要就是bean的定义信息。

后续我这边尽可能的对实例提供多种配置方法实现,以便于大家理解,我这边麻烦就麻烦点,但是要让大家感觉舒爽啊,哈哈!

原创文章,作者:9IM,如若转载,请注明出处:https://www.9im.cn/888.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注