【Spring4.0】基于注解的方式Bean配置

##一、注解的作用

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



##二、特定的注解

  • @Component: 基本注解, 标识了一个受 Spring 管理的组件
  • @Respository: 标识持久层组件
  • @Service: 标识服务层(业务层)组件
  • @Controller: 标识表现层组件



    ##三、示例代码(以MVC设计模式为例)

###1.持久层(Respository,也可以说是Model层)代码
####(1)新建一个名为top.cheungchingyin.beans.annotation.repository
注意!!
持久层(Respository)的代码全在该包内创建

####(2)创建一个名为UserRepository的接口,代码如下

package top.cheungchingyin.beans.annotation.repository;

public interface UserRepository {
	void save();
}

####(3)创建一个名为UserRepositoryImpl的Java类,实现UserRepository接口

package top.cheungchingyin.beans.annotation.repository;

import org.springframework.stereotype.Repository;

@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
	@Override
	public void save() {
		System.out.println("UserRepository save...");
	}

}

注解@Repository("userRepository")括号中的内容是为了设置bean的名字(即value属性),如果不指定,当spring扫描到的时候会以使用非限定类名, 第一个字母小写,即如果类名是UserRepositoryImpl,bean的名字则是userRepositoryImpl
###2.服务层(Service)代码
####(1)创建一个名为top.cheungchingyin.beans.annotation.service的包。
注意!!
持久层(Service)的代码全在该包内创建
####(2)创建一个名为UserService的Java类

package top.cheungchingyin.beans.annotation.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import top.cheungchingyin.beans.annotation.repository.UserRepository;

@Service
public class UserService {
	@Autowired
	@Qualifier("userRepository")//由于在UserRepository有两个实现类,不知道区分哪一个,所以需要@Qualifier指明是哪一个类
	private UserRepository userRepository;


	public void add() {
		System.out.println("UserService Add...");
		userRepository.save();
	}
}

注解 说明
@Service 表示该类为Service层的代码,让spring能够扫描识别出来放进IOC容器中
@Autowired 用于bean的自动注入,此处用于userRepository的自动注入
@Qualifier 中文叫做“合格者”,用于当某个接口有多个实现类的时候指明是使用哪一个类。如果没有此标签,spring可能检测到与两个实现类而不知需要注入哪一个类而报错

###3.视图层(View,此处用controller层代替)代码
####(1)创建一个名为top.cheungchingyin.beans.annotation.controller的包
注意!!
视图层(View,此处用controller层代替)的代码全在该包内创建
####(2)创建一个名为UserController的Java类

package top.cheungchingyin.beans.annotation.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import top.cheungchingyin.beans.annotation.service.UserService;

@Controller
public class UserController {
	@Autowired
	private UserService userService;

	public void execute() {
		System.out.println("UserController execute...");
		userService.add();
	}
}

此处使用@Controller注解来表示该类属于表现层的类。
由于UserService没有其他实现类,所以只需要使用@Autowired进行bean自动注入,而不用使用@Qualifier来指明哪一个bean。
###4.在src根目录下创建一个bean的配置文件beans-annotation.xml

<?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">
	<!-- 指定SpringIOC容器扫描的包 -->
	<!-- 可以指定resource-pattern指定扫描的资源 -->
	<context:component-scan base-package="top.cheungchingyin.beans.annotation" ></context:component-scan>
</beans>

注意!!

  • base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类. 。
  • 当需要扫描多个包时, 可以使用逗号分隔。
  • 如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤。

在标签<context:component-scan></context:component-scan>里面可以使用以下子节点进行过滤不想被IOC容器扫描的类。

  • <context:include-filter>:包含那些表达式的组件,该子节点需要use-default-filters配合使用
  • <context:exclude-filter>:指定排除那些指定表达式的组件
    如果type填的是 annotation,则expression填注解的全类名
    如果type填的是assignable,则expression填的是类的全类名,表示该类及该类的子类都不包括
    例如
<context:component-scan base-package="com.spring.annotation">
		<context:exclude-filter type="annotation"expression="org.springframework.stereotype.Repository"/></context:component-scan>

<context:include-filter><context:exclude-filter> 子节点支持多种类型的过滤表达式
这里写图片描述
###5.用于测试的主类main.java

package top.cheungchingyin.beans.annotation;

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

import top.cheungchingyin.beans.annotation.controller.UserController;

public class Main {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");
		UserController userController = (UserController) ctx.getBean("userController");
		userController.execute();
	}
}

测试结果
这里写图片描述



##四、总结

@Autowired 注解自动装配具有兼容类型的单个 Bean属性

  1. 构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解。

  2. 默认情况下, 所有使用 @Authwired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为false

  3. 默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在@Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter已指定注入 Bean 的名称。

  4. @Authwired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配。

  5. @Authwired注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean。

  6. @Authwired 注解用在 java.util.Map 上时, 若该Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值

猜你喜欢

转载自blog.csdn.net/qq_33596978/article/details/81181259