使用傳統的三層架構出現的問題.引入Spring底層實現原理來解決(工廠模式+反射+XML配置文件/註解)

以前寫的程式碼

mapper層

public interface PersonMapper {
    void selectPersonList();
}

public class PersonMapperImpl implements PersonMapper {
    @Override
    public void selectPersonList() {
        System.out.println("PersonMapperImpl selectPersonList");
    }
}

service層

public interface PersonService {
    void selectPersonList();
}
public class PersonServiceImpl implements PersonService {

    private PersonMapper personMapper = new PersonMapperImpl;

    @Override
    public void selectPersonList() {
        personMapper.selectPersonList();
    }
}

controller層

private PersonService personService = new PersonServiceImpl();

    public void selectPersonList(){
        personService.selectPersonList();
    }

可以發現的是程式碼耦合度非常的高,當我們修改PersonService的實現類需要修改多出程式碼,如何解決呢?

首先使用工廠模式創建對象

public class MyBeanFactory {
	public static Object getBean(String beanName) {
		if ("personService".equals(beanName)) {
			return new PersonServiceImpl();
		} else if ("personController".equals(beanName)) {
			return new PersonController();
		} else {
			return new PersonMapperImpl();
		}
	}
}

mapper層

public interface PersonMapper {
    void selectPersonList();
}

public class PersonMapperImpl implements PersonMapper {
    @Override
    public void selectPersonList() {
        System.out.println("PersonMapperImpl selectPersonList");
    }
}

service層

public interface PersonService {
    void selectPersonList();
}
public class PersonServiceImpl implements PersonService {

    private PersonMapper personMapper =(PersonMapper) MyBeanFactory.getBean("personMapper");

    @Override
    public void selectPersonList() {
        personMapper.selectPersonList();
    }
}

controller層

private PersonService personService = (PersonService) MyBeanFactory.getBean("personService");

    public void selectPersonList(){
        personService.selectPersonList();
    }

測試一下是可以達到效果的,但是還是存在程式碼耦合度高的問題

繼續優化,我們把MyBeanFactory的創建bean方法修改一下

public static Object getBean(String clazzName) {
	if (clazzName != null) {
		Object obj = null;
		try {
			obj = Class.forName(clazzName).newInstance();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	return null;
}

mapper層

public interface PersonMapper {
    void selectPersonList();
}

public class PersonMapperImpl implements PersonMapper {
    @Override
    public void selectPersonList() {
        System.out.println("PersonMapperImpl selectPersonList");
    }
}

service層

public interface PersonService {
    void selectPersonList();
}
public class PersonServiceImpl implements PersonService {

    private PersonMapper personMapper =(PersonMapper) MyBeanFactory.getBean("com.qbb.spring.mapper.impl.PersonMapperImpl");

    @Override
    public void selectPersonList() {
        personMapper.selectPersonList();
    }
}

controller層

private PersonService personService = (PersonService) MyBeanFactory.getBean("com.qbb.spring.service.impl.PersonServiceImpl");

    public void selectPersonList(){
        personService.selectPersonList();
    }

此時我們傳遞的是許可權定類名,降低了一些程式碼耦合度,但是又帶來了字元串硬編碼問題

繼續優化,修改MyBeanFactory

    // 創建對象時就載入
    public MyBeanFactory() {
        parseXML();
    }

    // 定義一個Map<String,Object>存儲bean對象
    private static Map<String, Object> map = new HashMap<>();

	// 解決字元串硬編碼
    public void parseXML() {
        // 創建解析XML對象
        SAXReader saxReader = new SAXReader();
        InputStream is = MyBeanFactory.class.getClassLoader().getResourceAsStream("MyBean.xml");
        try {
            // 讀取配置文件
            Document docment = saxReader.read(is);
            // 獲取跟標籤
            Element rootElement = docment.getRootElement();
            // 獲取字標籤
            List<Element> elements = rootElement.elements();
            for (Element element : elements) {
                String id = element.attributeValue("id");
                String clazz = element.attributeValue("class");
                Object newInstance = Class.forName(clazz).newInstance();
                map.put(id, newInstance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
	// 獲取bean
    public static Object getBean(String id) {
        return map.get(id);
    }