您的位置:首页 > 编程语言 > Java开发

Spring4.0学习笔记006——Bean的配置(基于注解)

2016-01-19 16:58 603 查看

1. 基于注解来配置Bean

1-2. 特定注解

组件扫描(component scanning):Spring能够从classpath下自动扫描,侦测并实例化具有“特定注解”的组件。这里的特定注解包括:

@Component:基本注解,标识了一个受Spring管理的组件

@Respository:建议标识持久层组件

@Service:建议标识服务层(业务层)组件

@Controller:建议标识表现层组件

虽然上述的特定注解中@Respository、@Service、@Controller三个注解被建议用于表示持久层、服务层、表现层的组件,但是这仅仅只是建议而且,任何组件上应用其中的任何一个注解都可以被Spring管理到。

1-2. Bean的命名规则

对于扫描到的组件,Spring有对应的命名规则:

使用非限定类名,第一个字母小写。

举例来说就是,如果带有某个注解的组件类其类名为UserInfo,那么在Spring容器中它所对应的Bean的名称(id)即为userInfo。

可以在注解中通过 value 属性值来显示标识组件所对应Bean的名称

举例来说就是,@Component(value=”userInfo”)

1-3. xml的相应设置

当在组件类上使用特定的注解之后,还需要在Spring的配置文件中声明< context:component-scan >节点,这就要求我们先要导入context命名空间。

< context:component-scan >节点的一些属性和子节点需要说明:

属性base-package:指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有类。当需要扫描多个包时,可以使用逗号分隔。

属性resource-pattern:用来过滤特定的类(如设resource-pattern=”subPackageName/*.class”)。

子节点< context:exclude-filter >:表示要排除在外的目标类。

子节点< context:include-filter >:表示要包含的目标类。

如果想要该子节点的过滤生效,还需要设置< context:component-scan >节点的属性use-default-filters值为false。

可以同时拥有若干个< context:include-filter >和< context:exclude-filter >子节点,而这些子节点又支持多种类型的过滤表达式。常用如下的两种过滤类型:

annotation:过滤目标是所有标注了指定注解的类

assinable:过滤目标是所有继承(实现)了指定类(接口)的类

看一看基于注解配置Bean的示例程序。

创建名为
com.yfyzwr.spring.beans.annotation
的package,在其中创建名为
TestComponent.java
的java文件。

@Component
public class TestComponent {

}


创建名为
com.yfyzwr.spring.beans.annotation.respository
的package,在其中创建名为
UserRespositoryImpl.java
的java文件。

@Repository(value="userRespository")
public class UserRespositoryImpl {

}


src目录下
创建名为
AnnotationContext.xml
的xml配置文件,为其添加context命名空间。

xmlns:context="http://www.springframework.org/schema/context"

<!-- 配置对注解的扫描范围 -->
<context:component-scan base-package="com.yfyzwr.spring.beans.annotation"></context:component-scan>


com.yfyzwr.spring.beans.annotation
包中创建包含main方法的java文件。

public class Main {

public static void main(String[] args) {

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("AnnotationContext.xml");

TestComponent testComponent = (TestComponent)context.getBean("testComponent");
System.out.println(testComponent);

UserRespositoryImpl userRespository = (UserRespositoryImpl)context.getBean("userRespository");
System.out.println(userRespository);
}

}


运行程序,查看输出结果。

com.yfyzwr.spring.beans.annotation.TestComponent@957cec

com.yfyzwr.spring.beans.annotation.respository.UserRespositoryImpl@3c944f

从输出结果可以得知,由注解@Component、@Repository所标注的类都已经被Spring容器所检测到,并且对其实例化。

2. 基于注解来自动装配Bean的属性

其实< context:component-scan >元素还会自动注册AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired、@Resource和@Inject注解的属性。

使用@Autowired注解能够自动装配具有兼容类型的单个Bean属性,它也是最常用的。

构造器、数据成员(即使是非 public)、一切具有参数的方法,它们都可以应用@Authwired 注解。

默认情况下, 所有使用@Authwired注解的属性都会被设置,所以当Spring找不到匹配的Bean来装配属性时(即Spring容器中没有属性所对应的类型),会抛出异常。如果该属性允许不被设置(就是有可能找不到对应的Bean类型), 那么可以设置@Authwired注解的required属性为false值。

默认情况下, 当Spring容器里存在多个类型兼容的 Bean 时,通过类型匹配来实现的自动装配将无法工作。此时可以为使用@Authwired注解的属性添加新的@Qualifier注解,并在@Qualifier注解里指定Bean的名称。Spring还允许对方法的形参标注@Qualifiter以指定注入 Bean 的名称。

举例来说就是,使用@Authwired注解的属性是interface类型,而Spring容器中又同时存在多个实现该接口的bean类,所以自动装配该属性时就不知道该为其赋值哪个实现类型的Bean对象。

看一看基于注解来自动装配Bean属性的示例程序。

修改UserRespositoryImpl类的实现。

@Repository(value="userRespository")
public class UserRespositoryImpl {

public void sayRespository(){

System.out.println("UserRespository say ...");
}
}


修改TestComponent类的实现。

@Component
public class TestComponent {

private UserRespositoryImpl respository;

public void execute(){
System.out.println("TestComponent execute ...");
respository.sayRespository();
}
}


修改main 方法的实现。

public static void main(String[] args) {

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("AnnotationContext.xml");

TestComponent testComponent = (TestComponent)context.getBean("testComponent");
testComponent.execute();
}


运行程序,查看输出结果。

java.lang.NullPointerException //抛出空指针异常,TestComponent 类的respository属性为空

再改TestComponent类的实现。

@Component
public class TestComponent {

@Autowired(required=false)
private UserRespositoryImpl respository;

//  @Autowired(required=false)
//  public void setRespository(UserRespositoryImpl respository) {
//      this.respository = respository;
//  }

public void execute(){
System.out.println("TestComponent execute ...");
respository.sayRespository();
}
}


运行程序,查看输出结果。

TestComponent execute …

UserRespository say …

9fcb
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring