//模拟三层架构
//dao
public class UserDao {
public void dao(){
System.out.println("dao层方法执行!!!");
}
}
//service
public class UserService {
private UserDao userDao=new UserDao();
public void service(){
System.out.println("service层方法执行!!!");
userDao.dao();
}
}
//servlet
public class UserServlet {
public static void main(String[] args) {
UserService service = new UserService();
userService.service();
}
}
//测试之前应将UserService类中创建UserDao实例的代码去掉
public class UserService {
private UserDao userDao;
public void service(){
System.out.println("service层方法执行!!!");
userDao.dao();
}
}
//使用自定义IoC框架中的容器获取UserService实例
public class UserServlet {
public static void main(String[] args) {
// UserService service = new UserService();
ApplicationContext applicationContext = new ClasspathXmlApplicationContext();
UserService userService = (UserService) applicationContext.getBean("userService");
userService.service();
}
}
//创建注解
@Target(ElementType.TYPE)//作用于类上,为创建实例做准备
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
String value() default "";
}
@Target(ElementType.FIELD)//作用于属性上,为依赖注入做准备
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
}
//在UserDao、UserService类上加@Component注解,在UserService类中的userDao属性上增加@Resource注解
//增加容器类,用于注解配置
public class AnnotationConfigurationApplicationContext implements ApplicationContext{
private Map<String,Object> beans=new HashMap<>();
public AnnotationConfigurationApplicationContext() {
BeanFactory beanFactory = new BeanFactory(this);
beanFactory.initBean();
beanFactory.dependencyInjection();
}
public void addBean(String id,Object object){
beans.put(id,object);
}
public Object getBean(String id){
return beans.get(id);
}
}
//修改BeanFactory
public class BeanFactory {
private List<BeanDifinition> beanDifinitions=new ArrayList<>();
private ApplicationContext applicationContext;
/**
* 在构造方法中读取配置文件,将配置文件内容存入beanDifinitions
*/
public BeanFactory(ApplicationContext applicationContext) {
this.applicationContext=applicationContext;
String path = this.getClass().getResource("/").getPath();//获取项目根目录
path=path.substring(1).replace("/",File.separator);
//如果是纯XML配置
if (applicationContext instanceof ClasspathXmlApplicationContext) {
......
}else if(applicationContext instanceof AnnotationConfigurationApplicationContext){//如果是注解配置
try {
//解析配置文件,获取扫描范围
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(path+"applicationContext.xml");
Element root = document.getRootElement();
Element element = root.element("component-scan");
String packageName = element.attributeValue("package");
packageName=packageName.replace(".",File.separator);
//递归扫描path所在路径下的所有文件
File directory = new File(path+packageName);
loopDirectory(directory,path);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
/**
* 递归遍历包下所有类,将被注解的类生成实例
*/
public void loopDirectory(File file,String path){
if (file.isDirectory()) {//如果是目录,递归遍历
File[] files = file.listFiles();
if (files != null && files.length > 0) {
for (File child : files) {
loopDirectory(child,path);
}
}
}else{//如果是文件,获取文件的绝对路径,从中筛选出所有以.class结尾的文件
String absolutePath = file.getAbsolutePath();
if (absolutePath.endsWith(".class")) {
//从绝对路径中获取类的全限定名
//示例:绝对路径为E:\a\b\c\com\woniu\dao\UserDao.class,path为E:\a\b\c\
//链式操作,replace(path,"")====》 com\woniu\dao\UserDao.class
//replace(".class","")====》 com\woniu\dao\UserDao
//replace(File.separator,".")====> com.woniu.dao.UserDao
String className=absolutePath.replace(path,"").replace(".class","").replace(File.separator,".");
try {
Class<?> c = Class.forName(className);
//查看类上是否有@Component注解
if (c.isAnnotationPresent(Component.class)) {
BeanDifinition beanDifinition = new BeanDifinition();
beanDifinition.setClassName(className);
String id=null;
//如果@Component注解没有指定value,使用的默认值(即类名首字母小写)
if (!"".equals(c.getDeclaredAnnotation(Component.class))) { id=c.getSimpleName().substring(0,1).toLowerCase()+c.getSimpleName().substring(1);
}else{//如果指定了value,以指定值为准
id=c.getDeclaredAnnotation(Component.class).value();
}
beanDifinition.setId(id);
//获取类中所有属性
Field[] fields = c.getDeclaredFields();
ArrayList<PropertyDifinition> propertyDifinitions = new ArrayList<>();
//如果属性上有@Resource注解,则进行依赖注入
if (fields != null && fields.length > 0) {
for (Field field : fields) {
if (field.isAnnotationPresent(Resource.class)) {
PropertyDifinition propertyDifinition = new PropertyDifinition();
propertyDifinition.setName(field.getName());
propertyDifinition.setRef(field.getName());
propertyDifinitions.add(propertyDifinition);
}
}
}
beanDifinition.setPropertyDifinitions(propertyDifinitions);
beanDifinitions.add(beanDifinition);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
......
}
测试
public class UserServlet {
public static void main(String[] args) {
// UserService service = new UserService();
AnnotationConfigurationApplicationContext applicationContext = new AnnotationConfigurationApplicationContext();
UserService userService = (UserService) applicationContext.getBean("userService");
userService.service();
}
}