自定义注解
package com.imooc.annotation.spring.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value=ElementType.METHOD)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Bean {
public String value();
}
package com.imooc.annotation.spring.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value=ElementType.TYPE)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Configuration {
}
package com.imooc.annotation.spring.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用在字段上,表示引用的Bean
*/
@Target(value=ElementType.FIELD)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Resource {
String value();
}
业务代码类:
public class BookHotelImpl implements IBook {
public void book() {
System.out.println("go hotel");
}
}
public class BookRestaurantImpl implements IBook {
public void book() {
System.out.println("go restaurant...");
}
}
public interface IBook {
public void book();
}
package com.imooc.annotation.spring;
import com.imooc.annotation.spring.annotation.Bean;
import com.imooc.annotation.spring.annotation.Configuration;
import com.imooc.annotation.spring.impl.BookHotelImpl;
import com.imooc.annotation.spring.impl.BookRestaurantImpl;
import com.imooc.annotation.spring.impl.IBook;
@Configuration
public class BeansXML {
@Bean(value="bookHotel")
public IBook bookHotel() {
return new BookHotelImpl();
}
@Bean(value="bookRestaurant")
public IBook bookRestaurant() {
return new BookRestaurantImpl();
}
@Bean(value="holiday")
public Holiday funnyHoliday() {
return new Holiday();
}
}
package com.imooc.annotation.spring;
import com.imooc.annotation.spring.annotation.Resource;
import com.imooc.annotation.spring.impl.IBook;
public class Holiday {
@Resource(value="bookRestaurant")
private IBook book;
public void setBook(IBook book) {
this.book = book;
}
public void haveFun() {
book.book();
}
}
工具类:
package com.imooc.annotation.spring;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.imooc.annotation.spring.annotation.Bean;
import com.imooc.annotation.spring.annotation.Configuration;
import com.imooc.annotation.spring.annotation.Resource;
public class ApplicationContext {
private Class<?> configClass;
private Map<String,Method> mapMethods;
//构造函数,
public ApplicationContext(Class<?> conClass) {
this.configClass = conClass;
if(checkConfigClass()) {
mapMethods = getDeclaredMethods(configClass);
}
}
//判断配置文件是否使用@Configuration注解
private boolean checkConfigClass() {
boolean useConfiguration = false;
useConfiguration = configClass.isAnnotationPresent(Configuration.class);
if(!useConfiguration) {
System.out.println("配置文件类 :" + configClass.getName() + "缺少@Configuration注解");
}
return useConfiguration;
}
//获取一个类中所有使用@Bean注解的方法
private Map<String,Method> getDeclaredMethods(Class<?> clazz) {
Map<String,Method> resultMap = new HashMap<String, Method>();
try {
for(Method m : clazz.getDeclaredMethods()) {
//获取每个方法的@bean注解
Bean beanMethod = m.getAnnotation(Bean.class);
if(null != beanMethod) {
String annoName = beanMethod.value();
//@Bean如果没有自定义value,使用方法名作为value
annoName = ("".equals(annoName)) ? m.getName() : annoName;
resultMap.put(annoName,m);
}
}
} catch (SecurityException e) {
System.out.println("读取配置文件错误" + e);
}
return resultMap;
}
//获取类实例
private <T> T getInstance(Class<T> clazz) {
T instance = null;
try {
instance = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return instance;
}
//根据bean名称获取bean
public <T> T getBean(String beanName) {
//Bean实例
T instance = null;
//配置文件类的实例
Object configObj = getInstance(configClass);
//遍历所有定义的Bean
Set<String> annoNames = mapMethods.keySet();
for(String annoName : annoNames) {
Method m = mapMethods.get(annoName);
if(beanName.equals(annoName)) {
try {
instance = (T) m.invoke(configObj);
//实例对象对应的Class类型
Class<?> instanceClass = instance.getClass();
for(Field field : instanceClass.getDeclaredFields()) {
//读取属性上的@Resouce注解信息
Resource res = field.getAnnotation(Resource.class);
if(null != res) {
//获取注解值
String resValue = res.value();
//判断是否已在配置文件类中已注册
Method refM = mapMethods.get(resValue);
if(null != refM) {
//获取属性对应的标准setter方法名称
String setterName = "set" + field.getName().substring(0, 1).toUpperCase()
+ field.getName().substring(1);
Method setter = instanceClass.getMethod(setterName,field.getType());
//执行setter方法
setter.invoke(instance,refM.invoke(configObj));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return instance;
}
}
测试类:
package com.imooc.annotation.spring;
public class Test {
public static void main(String[] args) {
//加载配置文件并获取上下文
ApplicationContext ctx = new ApplicationContext(BeansXML.class);
Holiday holiday = ctx.getBean("holiday");
holiday.haveFun();
}
}