spring之注解(三)Component

上篇文章中比较详细的介绍了依赖注入的相关注解,,尤其是@Autowired。但是我们对bean的定义声明还是放在xml的配置文件中。Spring当然提供了机制可以自动的扫描类路径,自动的向容器注册BeanDefinition。这就是Bean级别的注解。以上机制称为类路径扫描(clsspath-sacn),它是有相关注解(如@Component @Named @Bean)和beanFactoryPostProcessor和BeanPostProcessor实现的。本篇文章我们依次对各个注解进行说明。

本篇使用的示例代码继承之前的篇章。首先看注解。

@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 @Componentpublic @interface Service {}

另外@Controller 和 @Repository与之类似。Spring在web项目赋予这些注解特殊的含义。分别表示控制器和 数据访问层。

自定义

我们可以自定义注解,如下:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface MyComponent {String value();}使用

我们现在可以使用(自定义)注解直接标注在某个类上,此类就会自动的被Spring容器注册为BeanDefinition,我们可以对上篇文章中在xml中定义的bean改也注解的方式进行声明:

//使用元注解@Component("user1")public class UserServiceIml1 implements UserService{private UserDao userDao;@Overridepublic List<User> getUser() {return userDao.getUser();}//标注在set方法上。@Autowiredpublic void setUserDao(@Qualifier("userDao") UserDao userDao) {this.userDao = userDao;}}//使用自定义注解@MyComponent("user2")public class UserServiceIml2 implements UserService{//标注在字段上。@Autowired@Qualifier("userDao")private UserDao userDao;@Overridepublic 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的名称是user5public class UserServiceIml5 implements UserService{} @Component()//Bean的名称是userServiceIml3public 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官方文档。

我就想是一只草原中被牧童遗忘的羊,

spring之注解(三)Component

相关文章:

你感兴趣的文章:

标签云: