在使用Spring框架时,我们之前对于Bean的配置(怎么创建、各Bean之间的关系)都是使用的xml的配置文件配置的,现在我们更倾向的是使用注解开发,摈弃xml的配置文件。
接下来我们先了解一下注解是啥东西?
一、了解注解
定义注解
一个注解要定义注解的名称是什么?注解可以在哪里使用?其它可以定义什么属性?
我们先看一下注解的定义
@Target(value = {ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Component {
String value();
}
上面定义注解的名称是:Component
定义在注解上面的注解(称为元注解)Target指定了定义注解Component可以用在哪里,其中ElementType.TYPE表法可以使用在类和接口上
Retention这个元注解表示定义的Component这个注解的保持策略是怎么样的,其中RetentionPolicy.RUNTIME表示保持到运行期,这可以使得用反射的方式可以读取到它
String value(); 表示定义了一个属性,这个属性的类型是String,属性的名称是value
使用注解
根据上面定义的注解可知,它可以使用在类或接口上。我们使用下面的方式可以使用注解
public class Test {
public static void main(String[] args) {
// bean所在的包
String packageName = "com.xiaoxie.bean";
Map<String,Object> beanMap = new HashMap<>();
beanMap = getBeanNameMap(packageName);
System.out.println(beanMap);
}
/**
* 获取指定包下的所有bean
* @param packageName 文件夹
* @return
*/
private static Map<String, Object> getBeanNameMap(String packageName) {
Map<String,Object> beanMap = new HashMap<>();
String path = packageName.replaceAll("\\.", "/");
URL url = ClassLoader.getSystemClassLoader().getResource(path);
File file = new File(url.getPath());
File[] files = file.listFiles();
for (File f : files) {
if (f.isDirectory()) {
beanMap.putAll(getBeanNameMap(packageName + "." + f.getName()));
} else {
String className = packageName + "." + f.getName().split("\\.")[0];
try {
Class<?> clazz = Class.forName(className);
if(clazz.isAnnotationPresent(Component.class)) {
// 如果类上有@Component注解存在
Component component = clazz.getAnnotation(Component.class);
String beanId = component.value(); // 获取注解上的value属性值
Object obj = clazz.newInstance(); // 创建对象
beanMap.put(beanId, obj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return beanMap;
}
}
通过上面的简解说明,我们了解了注解的基本使用,接下来看看Spring中提供的一些注解
二、Spring中常用注解
声明Bean相关注解
@Component
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
@Controller
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Service
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Repository
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
从上面注解我们可以看到@Controller,@Service,@Repository这三个注解都是@Component注解的别名。也就是说其实这四个注解的功能都是一样的,那为什么同样功能的要搞出四个注解来呢?
定义出多个不同的注解Spring是考虑到我们的应用会分层,不同的层我们使用不同的注解这样代码上可读性就更好了。一看