您的位置:首页 > 编程语言 > Java开发

Spring:源码解读Spring IOC原理

2017-01-19 11:17 483 查看


经典链接:http://www.cnblogs.com/ITtangtang/p/3978349.html

http://www.cnblogs.com/dazhaxie/archive/2012/06/18/2553300.html

Spring的BeanFactoryPostProcessor和BeanPostProcessor的详解: http://blog.csdn.net/caihaijiang/article/details/35552859
动态注册bean: http://blog.csdn.net/buyaore_wo/article/details/8119577



package com.yc.feed.bean;

import com.le.config.client.ConfigManager;
import com.yc.feed.domain.config.JdbcDataSourceConfig;
import com.yongche.config.database.DataSourceInstance;
import com.yongche.config.database.Database;
import com.yongche.config.database.DatabaseConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import javax.sql.DataSource;
import java.util.List;

/**
* <p>operation-parent
* <p>com.yongche.config.database
*
* @author stony
* @version 下午4:44
* @since 2017/1/18
*/
public class ConfigCenterDataSource implements BeanDefinitionRegistryPostProcessor {

String SLAVE_NAME = "%s_slave_%s";

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
JdbcDataSourceConfig databaseConfig = ConfigManager.get(JdbcDataSourceConfig.class);
for (Database database : databaseConfig.getDatabases()) {
registerDataSourceBeanDefinition(database, registry);
}
}

protected void registerDataSourceBeanDefinition(Database database,BeanDefinitionRegistry registry) {
DataSourceInstance master = database.getMaster();
List<DataSourceInstance> slaves = database.getSlaves();
registry.registerBeanDefinition(database.getName(), buildDataSourceBeanDefinition(master, false));
if (slaves != null && (!slaves.isEmpty())) {
for (int i = 0, size = slaves.size(); i < size; i++) {
registry.registerBeanDefinition(String.format(SLAVE_NAME, database.getName(), i), buildDataSourceBeanDefinition(slaves.get(i), true));
}
}
}

Class<?> dataSourceClass = HikariDataSource.class;
String driverClassName = "com.mysql.jdbc.Driver";
protected RootBeanDefinition buildDataSourceBeanDefinition(DataSourceInstance dsi, boolean readOnly) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(dataSourceClass);
int port = dsi.getPort();
if (port == 0) {
port = 3306;
}
String url = String.format("jdbc:mysql://%s:%s/%s", dsi.getHost(), port, dsi.getDb());
int maximumPoolSize = dsi.getMaximumPoolSize();
if (maximumPoolSize < 10) {
maximumPoolSize = 10;
}
if (maximumPoolSize > 1000) {
maximumPoolSize = 1000;
}
int connectionTimeout = Math.max(dsi.getConnectionTimeout(), 300);

beanDefinition.getPropertyValues().add("driverClassName", driverClassName);
beanDefinition.getPropertyValues().add("jdbcUrl", url);
beanDefinition.getPropertyValues().add("username", dsi.getUsername());
beanDefinition.getPropertyValues().add("password", dsi.getPassword());
beanDefinition.getPropertyValues().add("maximumPoolSize", maximumPoolSize);
beanDefinition.getPropertyValues().add("connectionTimeout", connectionTimeout);
beanDefinition.getPropertyValues().add("autoCommit", true);
beanDefinition.getPropertyValues().add("readOnly", readOnly);
return beanDefinition;
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

}
}





ApplicationContext是spring的核心,Context通常解释为上下文环境,用“容器”来表述更容易理解一些,ApplicationContext则是“应用的容器了”了。

spring把bean放在这个容器中,在需要的时候,用getBean()方法取出,在web应用中,会用到webApplicationContext,继承自ApplicationContext

在web.xml初始化WebApplicationContext:

   <context-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>/WEB-INF/applicationContext.xml</param-value>

  </context-param>

<listener>

     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

或者用ContextLoaderServlert亦可(加<load-on-startup>1</load-on-startup>)

========================================================================================================================

Spring MVC Framework大至流程如下:
当web程序启动的时候,ContextLoaderServlet会把对应的配置文件信息读取出来,通过注射去初始化控制器DispatchServlet. 而当接受到一个HTTP请求的时候, DispatchServlet会让HandlerMapping去处理这个请求.HandlerMapping根据请求URL(不一定非要是URL,完全可以自定义,非常灵活)来选择一个Controller. 然后DispatchServlet会在调用选定的Controller的handlerRequest方法,并且在这个方法前后调用这个Controller的interceptor(假如有配置的话),然后返回一个视图和模型的集合ModelAndView.框架通过ViewResolver来解析视图并且返回一个View对象,最后调用View的render方法返回到客户端
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java