Spring核心结构
Spring的核心思想
AOP
- OOP:面向对象编程,特征是继承,封装,多态,解决垂直体系的代码重复
- AOP:面向切面,解决横切代码的重复问题,以及抽取非业务代码,明确业务逻辑.常见应用有事务控制,日志记录,权限控制等
IOC
控制反转: 对象创建交由外部容器实现,解决对象间的耦合.
DI
依赖注入:与IOC角度不同,IOC是站在对象角度上,对象的创建交由容器维护,DI是站在容器的角度上,容器会提供对象依赖的其他对象,供给其使用
MVC的发展
传统MVC
public class TransferServlet extends HttpServlet { private TransferService transferService = new TransferServiceImpl(); }
public class TransferServiceImpl implements TransferService { private AccountDao accountDao = new JdbcAccountDaoImpl(); }
|
问题
1.代码耦合,每层都持有下一层的实现类对象
2.service层没有进行事务控制,方法执行中出现异常时,可能会导致数据库数据错乱
解决方案
问题1:
除了通过new创建对象外,我们还可以通过反射的方式创建,可以将对象创建提取到一个统一的地方执行,并提供一个方法去获取对象.如工厂类
问题2:
为Service层添加事务控制,但是JDBC的事务是控制在dao层,若一个service层中调用dao层多个db方法,这样就会导致出现多个事务,我们需要让这多个db方法属于一个Connection,这样才能实现Service层的事务控制.
代码示例
1.提取对象到XML
<beans> <bean id="transferService" class="com.ww.transfer.service.impl.TransferServiceImpl"> <property name="AccountDao" ref="accountDao"/> </bean> <bean id="accountDao" class="com.ww.transfer.dao.impl.JdbcAccountDaoImpl"> </bean> </beans>
|
2.通过工厂类创建对象
public class BeanFactory {
private static final Map<String, Object> map = new HashMap<>();
static { InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"); SAXReader saxReader = new SAXReader(); try { Document document = saxReader.read(resourceAsStream); Element rootElement = document.getRootElement(); List list = rootElement.selectNodes("//bean"); for (Object value : list) { Element element = (Element) value; String id = element.attributeValue("id"); String clazz = element.attributeValue("class"); Class<?> aClass = Class.forName(clazz); Object o = aClass.newInstance(); map.put(id, o); } List propertyNodes = rootElement.selectNodes("//property"); for (Object propertyNode : propertyNodes) { Element element = (Element) propertyNode; String name = element.attributeValue("name"); String ref = element.attributeValue("ref");
String parentId = element.getParent().attributeValue("id"); Object parentObject = map.get(parentId);
Method[] methods = parentObject.getClass().getMethods(); for (Method method : methods) { if (("set" + name).equalsIgnoreCase(method.getName())) { Object propertyObject = map.get(ref); method.invoke(parentObject, propertyObject); } } map.put(parentId, parentObject); } } catch (DocumentException | ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); } }
public static Object getBean(String id) { return map.get(id); } }
|
3.增加ConnectionUtils维护唯一Connection
public class ConnectionUtils {
private ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
public Connection getCurrentThreadConn() throws SQLException {
Connection connection = threadLocal.get(); if (connection == null) { connection = DruidUtils.getInstance().getConnection(); threadLocal.set(connection); } return connection; }
}
|
4.增加ProxyFactory生成代理类,插入事务处理逻辑
public class ProxyFactory {
private TransactionManager transactionManager;
public void setTransactionManager(TransactionManager transactionManager) { this.transactionManager = transactionManager; }
public Object getProxy(Object target) { return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> { Object result; try { transactionManager.beginTransaction(); result = method.invoke(target, args); transactionManager.commit(); } catch (Exception e) { e.printStackTrace(); transactionManager.rollback(); throw e.getCause(); } return result; }); }
}
|