内容简介:前两章我们已经实现了思路如下:
What a sweet burden!A joyful sorrow!
概述
前两章我们已经实现了 setter 注入和 constructor 注入,本章我们来继续实现 annotation 注入。
思路如下:
- 读取
xml文件 - 对指定
base-package进行扫描,找到对应那些标记为@Component的类,创建BeanDefinition- 把
base-package下面的class变成Resource - 使用
ASM读取Resource中的注解信息 - 创建
BeanDefinition
- 把
- 通过
BeanDefinition创建Bean的实例,根据注解来注入
准备测试类
AccountDao
package com.niocoder.dao.v4;
import com.niocoder.stereotype.Component;
@Component
public class AccountDao {
}
ItemDao
package com.niocoder.dao.v4;
import com.niocoder.stereotype.Component;
@Component
public class ItemDao {
}
NioCoderService
package com.niocoder.service.v4;
import com.niocoder.beans.factory.Autowired;
import com.niocoder.dao.v4.AccountDao;
import com.niocoder.dao.v4.ItemDao;
import com.niocoder.stereotype.Component;
/**
* 测试注解
*/
@Component(value = "nioCoder")
public class NioCoderService {
@Autowired
private AccountDao accountDao;
@Autowired
private ItemDao itemDao;
public AccountDao getAccountDao() {
return accountDao;
}
public ItemDao getItemDao() {
return itemDao;
}
}
bean-v4.xml
增加命名空间避免元素冲突,详情参考 链接
<?xml version="1.0" encoding="UTF-8"?>
<!-- 增加namespace-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context">
<!-- 扫描哪个包下面的文件 -->
<context:component-scan base-package="com.niocoder.dao.v4,com.niocoder.service.v4">
</context:component-scan>
</beans>
Component和Autowired注解
Component 注解主要用于类名上,表明该类为一个注册到容器中的 bean 。 Autowired 注解主要用于属性和方法(构造方法, setter 方法)上,表明该类实例化时会自动将对应的属性注入。
Component
package com.niocoder.stereotype;
import java.lang.annotation.*;
/**
* Component 注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
String value() default "";
}
Autowired
package com.niocoder.beans.factory;
import java.lang.annotation.*;
/**
* Autowired注解
*/
@Target({ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default false;
}
PackageResourceLoader
把 base-package 下面的 class 变成 Resource
PackageResourceLoader
/**
* 将一个目录下的类文件加载为资源文件
*
* @author zhenglongfei
*/
@Log
public class PackageResourceLoader {
/**
* 给定一个包的路径,将包下面的文件转换为Resource
*
* @param basePackage
* @return
* @throws IOException
*/
public Resource[] getResource(String basePackage) throws IOException {
Assert.notNull(basePackage, "basepackage must not be null");
String location = ClassUtils.convertClassNameToResourcePath(basePackage);
URL url = ClassUtils.getDefaultClassLoader().getResource(location);
File rootDir = new File(url.getFile());
Set<File> matchingFiles = retrieveMatchingFiles(rootDir);
Resource[] resources = new Resource[matchingFiles.size()];
int i = 0;
for (File file : matchingFiles) {
resources[i++] = new FileSystemResource(file);
}
return resources;
}
private Set<File> retrieveMatchingFiles(File rootDir) throws IOException {
if (!rootDir.exists()) {
log.info("Skipping [" + rootDir.getAbsolutePath() + "] because is not exist");
}
if (!rootDir.isDirectory()) {
log.info("Skipping [" + rootDir.getAbsolutePath() + " ] because it a Directory");
}
if (!rootDir.canRead()) {
log.info("Cannot search for matching files underneath directory [" + rootDir.getAbsolutePath() +
"] because the application is not allowed to read the directory");
return Collections.emptySet();
}
Set<File> result = new LinkedHashSet<File>(8);
doRetrieveMatchingFiles(rootDir, result);
return result;
}
protected void doRetrieveMatchingFiles(File dir, Set<File> result) throws IOException {
File[] dirContents = dir.listFiles();
if (dirContents == null) {
log.info("Could not retrieve contents of directory [" + dir.getAbsolutePath() + "]");
return;
}
for (File content : dirContents) {
if (content.isDirectory()) {
if (!content.canRead()) {
log.info("Skipping subdirectory [" + dir.getAbsolutePath() +
"] because the application is not allowed to read the directory");
} else {
doRetrieveMatchingFiles(content, result);
}
} else {
result.add(content);
}
}
}
}
递归的读取一个指定的包目录转换为Resource
PackageResourcesLoaderTest
public class PackageResourcesLoaderTest {
@Test
public void testGetResource() throws Exception {
PackageResourceLoader loader = new PackageResourceLoader();
Resource[] resource = loader.getResource("com.niocoder.dao.v4");
Assert.assertEquals(2, resource.length);
}
}
测试PackageResourceLoader
debug调试
代码下载
代码下载
参考资料
以上所述就是小编给大家介绍的《Small Spring系列五:annotation Injection(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
松本行弘的程序世界
松本行弘 / 柳德燕、李黎明、夏倩、张文旭 / 人民邮电出版社 / 2011-8 / 75.00元
《松本行弘的程序世界》是探索程序设计思想和方法的经典之作。作者从全局的角度,利用大量的程序示例及图表,深刻阐述了Ruby编程语言的设计理念,并以独特的视角考察了与编程相关的各种技术。阅读《松本行弘的程序世界》不仅可以深入了解编程领域各个要素之间的关系,而且能够学到大师的思考方法。 《松本行弘的程序世界》面向各层次程序设计人员和编程爱好者,也可以供相关技术人员参考。一起来看看 《松本行弘的程序世界》 这本书的介绍吧!