Spring框架笔记(十二)——通过注解配置bean

配置 bean有两种方式:基于 XML 文件的方式;基于注解的方式(基于注解配置 Bean;基于注解来装配 Bean 的属性)

之前我们都是在IOC配置文件xml中配置bean,现在我们尝试在代码源文件中通过注解的方式标注特定类对应的Bean。


在 classpath 中扫描组件

组件扫描(component scanning):  Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件. 

特定组件包括:

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

    @Respository: 标识持久层组件

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

    @Controller : 标识表现层组件

对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称

当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明 <context:component-scan> :

    base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类. 

    当需要扫描多个包时, 可以使用逗号分隔.

    如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示例:

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

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

    <context:component-scan> 下可以拥有若干个 <context:include-filter> 和 <context:exclude-filter> 子节点

    <context:include-filter> 和 <context:exclude-filter> 子节点支持多种类型的过滤表达式:

Spring框架笔记(十二)——通过注解配置bean_第1张图片

好,我还是用例子来说说:

首先,我们定义一组类,分别是表示层的控制器、持久层的访问器、业务层的调用器、模型层的数据bean。

Spring框架笔记(十二)——通过注解配置bean_第2张图片

package com.happyBKs.annotations.beans;

import org.springframework.stereotype.Component;

@Component
public class PositionBean {

}
package com.happyBKs.annotations.controllers;

import org.springframework.stereotype.Controller;

@Controller
public class PositionController {

	public void execute()
	{
		System.out.println("PositionController execute...");
	}
}
package com.happyBKs.annotations.respository;


public interface PositionRespository {
	void save();
}
package com.happyBKs.annotations.respository;

import org.springframework.stereotype.Repository;

@Repository("positionRespository")
public class PositionRespositoryImpl implements PositionRespository {

	public void save() {
		// TODO Auto-generated method stub
		System.out.println("PositionRespository save...");
		
	}

}
package com.happyBKs.annotations.services;

import org.springframework.stereotype.Service;

@Service
public class PositionService {

	public void save()
	{
		System.out.println("PositionService save...");
	}
}

注意到没?我们为不同的bean注解了不同的注解,分别对应不同的层次。但是其实我们可以使用@Respository注解Service层的bean,@Component注解表示层的bean,都是没问题的。这里注解标识的不同制式出于规范的需要。

IOC配置文件这时候不需要在配置bean了,但是还是需要为spring自动扫描源码包寻找注解bean指明需要扫描的包名。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

	<!-- 指定Spring IOC容器扫描的包 -->
	<context:component-scan base-package="com.happyBKs.annotations"></context:component-scan> 
	
</beans>

这里有个IDE的小细节,之前我们可以看到我们定义的那些类的源文件的LOGO就是一般的Java源文件LOGO。但是配置文件写好之后,发现源文件上出现了S。

Spring框架笔记(十二)——通过注解配置bean_第3张图片


测试代码:

package com.happBKs.spring.iocaop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.happyBKs.annotations.beans.PositionBean;
import com.happyBKs.annotations.controllers.PositionController;
import com.happyBKs.annotations.respository.PositionRespository;
import com.happyBKs.annotations.services.PositionService;

public class TestAnnotation {

	@Test
	public void test1()
	{
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans-annotation.xml");
		PositionBean pb=(PositionBean)ac.getBean("positionBean");
		System.out.println(pb);
		PositionController pc=(PositionController)ac.getBean("positionController");
		System.out.println(pc);
		PositionRespository pr=(PositionRespository)ac.getBean("positionRespository");
		System.out.println(pr);
		PositionService ps=(PositionService)ac.getBean("positionService");
		System.out.println(ps);
	}
}

输出:

com.happyBKs.annotations.beans.PositionBean@10e3c6a3

com.happyBKs.annotations.controllers.PositionController@5a05fffe

com.happyBKs.annotations.respository.PositionRespositoryImpl@3fe9aade

com.happyBKs.annotations.services.PositionService@5d0f59a


当然我们也可以通过前面介绍的方,过滤或者追加相关的包或类。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

	<!-- 指定Spring IOC容器扫描的包 -->
<!-- 	<context:component-scan base-package="com.happyBKs.annotations"></context:component-scan> -->
	
		<!-- 指定Spring IOC容器扫描的包 -->
<!-- 	<context:component-scan base-package="com.happyBKs.annotations"
	resource-pattern="beans/*.class"></context:component-scan> -->

	<!-- 指定Spring IOC容器扫描的包 -->
<!-- 	<context:component-scan base-package="com.happyBKs.annotations">
		<context:exclude-filter type="assignable"
			expression="com.happyBKs.annotations.controllers.PositionController" />
	</context:component-scan> -->


	<context:component-scan base-package="com.happyBKs.annotations">
		<context:exclude-filter type="annotation"
			expression="com.happyBKs.annotations.respository.PositionRespositoryImpl" />
	</context:component-scan>


</beans>

当相关类被排除了,那么相应的bean就没有了,测试程序会报错。


这里需要特别注意的是,注解方式构造bean,默认的bean的Id名字是类名的首字母小写后的字符串。但是如果在注解时指明了注解名称的除外。




你可能感兴趣的:(spring)