Spring入门3——注解篇

Spring2.5之后,引入了大量的注解,现在到现在位置已经可以使用注解来完成大部分的XML配置功能。


因为注解和Java代码是在同一文件中的,但是XML配置采用的是独立的配置文件,如果使用XML配置文件,程序员在开发的时候,往往需要在代码和配置文件中不停的切换,这样会影响开发效率。相对来说使用注解的方式,更易于阅读,而不是全部配置文件堆成一大片。

但是XML也并不是完全没有优势,在完成整个项目之后,如果在其他项目中,只是依赖关系不同的话,只修改配置文件就应用于其他项目当中,而注解的方式则需要改写源代码才可以。

但毫无疑问的是,使用注解配置的方式越来越多人使用。


上面说了,注解和Java代码是位于同一文件中的,那么Spring如何知道将哪些类作为bean处理呢?

Spring将几个特殊的注解来标注bean

1.@Component: 标注一个普通的spring Bean类。

2.@Controller: 标注一个控制器组件类。

3.@Service: 标注一个业务逻辑组件类。

4.@Repository: 标注一个DAO组件类。


一般来说,用这些注解来标注的类的bean的id是bean类名,将首字母小写。

除了这几种注解之外,Spring也会将这些注解的子注解标注的类当作bean,这涉及到自定义注解,将上面的注解作为元注解即可。

一般来说,我们都会尽量的细致的使用注解,如业务逻辑层使用@Service注解,持久层使用@Repository,使得阅读便于理解,并且在Spring更高的版本中,会存在更加深层的语义。


单单使用注解标注类是不够的,还需要在XML文件中告诉Spring,你需要将哪里的类当作bean,而不能让Spring扫描整个文件去寻找,以减小Spring的开销。

<context:component-scan base-package="..."/>
在xml配置文件中,增加这么一句,告诉Spring扫描这个包下的所有文件。


例子:

xml配置文件:

<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-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	<context:component-scan base-package="Spring.AnnotationTest2" />
</beans>
这里需要增加扫描的包名,在schemaLocation中记得加入注解的命名空间。

public interface IDAO {
	public void save(String data);
}

@Repository
public class DAOImpl implements IDAO{

	public void save(String data) {
		System.out.println("save to database: " + data);
	}
	
}
测试类:

public class BeanTest {

	private ClassPathXmlApplicationContext context;
	
	@Test
	public void Test1() {
		try {
			context = new ClassPathXmlApplicationContext("classpath:spring-annotation.xml");
			context.start();
			IDAO iDAO = (IDAO) context.getBean("DAOImpl");
			iDAO.save("myData");
		} catch (Exception e){
			e.printStackTrace();
		}
		context.destroy();
	}
}
这样,Spring就会为DAOImpl自动的创建一个bean对象,我们可以通过上下文获取。这里细心的同学会注意到,bean的id并不是我上面所说的首字母小写,而是原名,这里的主要因为是因为我的类名前两个字母都是大写的,这样的话就会是原名,而如果只有第一个字母大写,那么还是按照上面所说的。


其实我们可以自己自定义bean的id,只需要在@Repository后面增加("id名字")就可以自定义id。

如:

@Repository("iDAO")
public class DAOImpl implements IDAO{

	public void save(String data) {
		System.out.println("save to database: " + data);
	}
	
}
除此之外,我们还可以通过实现BeanNameGeneration这个接口来重新规定bean的id的命名规则,默认的命名规则就是首字母小写。


在前面说过,我们可以通过在配置文件中增加扫描的配置告诉Spring我们需要扫描哪里的包。其实我们可以更加细致的告诉它。

我们可以通过为<context:component-scan>添加<include-filter...>或<exclude-filter...>两种过滤器,他们的作用是在扫描的时候进行判断,是否满足要求。

<include-filter...>: 满足该规则的java类会被当初bean类处理。
<exclude-filter...>: 指定满足该规则的java类不会被当初bean类处理。



如果是bean的依赖关系,那么用注解的方式如何实现呢?

这就需要用到@Autowired注解。

@Autowired 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。


例如:

public interface IService {
	public void save(String data);
}
@Service
public class ServiceImpl implements IService {
	
	@Autowired
	private IDAO iDAO;

	public void save(String data) {
		iDAO.save(data);
	}
	
}
在ServiceImpl类中,有关于IDAO类的依赖,而我们仅仅需要使用@Autowired注解去标注一下,就可以自动的完成装配。是不是特别简单?

如果使用@Autowired标注成员变量,默认通过byType的类型进行装配。

也可以通过标注方法和构造器的方式来达到目的。

如果自动装配找不到对应的类型,默认会抛出异常,如果我们希望找不到的时候,值为null的话,就要设置required = false,就不会抛出异常了。


而对于一些众所周知的接口,例如BeanFactory,ApplicationContext,Environment,ResourceLoader,ApplicationEventPublisher,MessageSource等等,我们可以直接通过@Autowired对它们进行自动装配,就可以得到这些对象了,而不必像在XML篇里面实现Aware接口来获取对象。


数组使用@Autowired

对于数组,Set,Map使用@Autowired注解的话,得到的是对应的类型的所有的bean。

例如我们有接口IDAO,类DAOImpl1和DAOImpl2,如果我们使用@Autowired标注List<IDAO>的话,List中会存在两个bean,分别对应DAOImpl1和DAOImpl2。

对于数组,我们可以定义他们的顺序,使用@Order(value = "...")标注,按照value从小到大进行排序。

例如:使用@Order(value = 1)标注DAOImpl1,使用value = 2标注DAOImpl2,则遍历的时候,会先访问DAOImpl1。



除了上面的几种注解之外,还有@Scope,@Qualifier,@Resource,@Bean,@Configuration,@ImportResource,@Value等注解。


@Scope

用来指明bean的作用域,在XML篇说过,取值有5中,默认是单例singleton.


@Qualifier

@Qualifier注解可以缩小或指定自动装配的范围。如果在使用@Autowired自动装配的过程中,出现了多个同种类型的bean,那么Spring就不知道选哪个好了,就会抛出异常。这时可以使用@Qulifier注解指定装配的对象。可以用来标注类和方法的参数。


@Resource

@Resource和@Autowired注解十分类似,都是做bean的注入,区别是@Resource并不是Spring的注解,并且默认装配以byName的方式进行装配。


@Bean @Configuration

这两个注解通常是一起使用的。通过这两个注解,可以将XML配置的方式转换成通过Java的方式来配置,减小了xml的配置。

例子:

@Configuration
public class MyConfig {
	
	@Bean
	public IDAO getIDAO() {
		return new DAOImpl();
	}
}
<bean id = "getIDAO" class = "DAOImpl"></bean>
两种方式是等同的。可以将XML配置转移成Java代码的方式进行配置。默认按照方法名作为id,我们也可以自定义id,@Bean("...")来自定义。


@ImportResource @Value

这两个注解配合使用可以加载properties资源文件,并且读取其中的键值对,这样,到项目后期,我们就只需要修改键值对中的值。

由于@ImportResource只能读取xml文件,所以我们通过在xml文件中加载properties文件,类中加载xml文件的方法来读取properties中的键值对。

例如:

有properties文件:

jdbc.username="myName"
jdbc.password="myPassword"
在xml文件中加入如下语句:

<context:property-placeholder location = "classpath:jdbc.properties"/>
通过这个标签让Spring加载properties文件。

在Java配置文件中读取properties的键值对:

@Configuration
@ImportResource("classpath:spring-annotation.xml")
public class MyConfig {
	
	@Value("${jdbc.username}")
	private String username;
	
	@Value("${jdbc.password}")
	private String password;
	
	@Bean
	public IDAO getIDAO() {
		System.out.println(username + " " + password);
		return new DAOImpl();
	}
}
如此一来,就可以在处理bean之前读取properties中的值。成功的加载了文件。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值