当前位置: 首页 > news >正文

网站发布和管理系统阿里巴巴的网站二维码怎么做

网站发布和管理系统,阿里巴巴的网站二维码怎么做,一般公司做网站多少钱,帮别人做网站要投资吗文章目录 手写Spring与基本原理解析简介写一个简单的Bean加载容器定义一个抽象所有类的BeanDefinition定义一个工厂存储所有的类测试 实现Bean的注册定义和获取基于Cglib实现含构造函数的类实例化策略Bean对象注入属性和依赖Bean的功能Spring.xml解析和注册Bean对象实现应用上下… 文章目录 手写Spring与基本原理解析简介写一个简单的Bean加载容器定义一个抽象所有类的BeanDefinition定义一个工厂存储所有的类测试 实现Bean的注册定义和获取基于Cglib实现含构造函数的类实例化策略Bean对象注入属性和依赖Bean的功能Spring.xml解析和注册Bean对象实现应用上下文向虚拟机注册钩子实现Bean对象的初始化和销毁方法感知容器对象Bean对象作用域以及FactoryBean的实现和使用基于观察者实现容器事件和事件监听器AOP切面AOP动态代理融入到Bean的生命周期通过注解配置和包自动扫描的方式完成Bean对象的注册通过注解给属性注入配置和Bean对象循环依赖事务功能设计实际使用--JDBCTemplate整合ORM框架 手写Spring与基本原理解析 详细请跳转 https://bugstack.cn/md/spring/develop-spring 这里是学习上述小博哥的《手写Spring》做的简易记录夹杂着很多个人私活建议直接看链接 简介 从SpringBean的加载流程博文中可以知道Spring的简易加载流程 Spring bean的生命周期包括实例化、属性赋值、初始化前回调、自定义初始化、初始化后回调、初始化完成、销毁前回调、自定义销毁这些阶段和回调方法。 接下来讲根据上述流程逐步深入 写一个简单的Bean加载容器 定义一个抽象所有类的BeanDefinition 首先进行简单的容器设计我们需要将一个个的类进行统一的定义这个定义名称为BeanDefinition他包含众多的属性包括是否是单例类的名称等等。为了减少代码的复杂性这里不再展开 简单定义这个类 public class BeanDefinition {private Object object;public BeanDefinition(Object object) {this.object object;}public Object getBean() {return object;} }在这个类中BeanDefinition单纯代表这个类的统一接口真正的类是object后面我们可以通过getBean的方式直接获取这个object。 定义一个工厂存储所有的类 实体类有了统一的接口后就可以建立一个工厂这个工厂叫做“Bean”工厂建立的所有的类都以Map的方式放到这个工程中后续可以直接调用 Map中主键就是我们定义的名称也就是平常xml中的bean的id import java.util.Map; import java.util.concurrent.ConcurrentHashMap;public class BeanFactory {private MapString, BeanDefinition beanDefinitionMap new ConcurrentHashMap();public Object getBean(String name) {return beanDefinitionMap.get(name).getBean();}public void registerBeanDefinition(String name, BeanDefinition beanDefinition){beanDefinitionMap.put(name, beanDefinition);} }这样一个简易的容器实际上已经建好了我们只需要往这个bean里面塞class就可以 测试 定义一个实体类UserService public class UserService {public void query(){System.out.println(用户名称查询);} }测试 public class ApiTest {public static void main(String[] args) {//定义好bean工厂BeanFactory beanFactory new BeanFactory();//注册bean对象BeanDefinition beanDefinition new BeanDefinition(new UserService());beanFactory.registerBeanDefinition(userService, beanDefinition);//获取类对象UserService userService (UserService) beanFactory.getBean(userService);userService.query();} } 这样一个简单的Spring Bean容器实际就建立好了 实现Bean的注册定义和获取 定义 BeanFactory 这样一个 Bean 工厂提供 Bean 的获取方法 getBean(String name)之后这个 Bean 工厂接口由抽象类 AbstractBeanFactory 实现。 BeanFactory 的定义由 AbstractBeanFactory 抽象类实现接口的 getBean 方法 而 AbstractBeanFactory 又继承了实现了 SingletonBeanRegistry 的DefaultSingletonBeanRegistry 类。这样 AbstractBeanFactory 抽象类就具备了单例 Bean 的注册功能。 AbstractBeanFactory 中又定义了两个抽象方法getBeanDefinition(String beanName)、createBean(String beanName, BeanDefinition beanDefinition) 而这两个抽象方法分别由 DefaultListableBeanFactory、AbstractAutowireCapableBeanFactory 实现。 最终 DefaultListableBeanFactory 还会继承抽象类 AbstractAutowireCapableBeanFactory 也就可以调用抽象类中的 createBean 方法了。 基于Cglib实现含构造函数的类实例化策略 通过策略模式拆分单例构造与有参数构造判断条件为是否有参数构造时使用Cglib1、BeanFactory 中我们重载了一个含有入参信息 args 的 getBean 方法这样就可以方便的传递入参给构造函数实例化了。 2、在实例化接口 instantiate 方法中添加必要的入参信息包括beanDefinition、 beanName、ctor、args 其中 Constructor 你可能会有一点陌生它是 java.lang.reflect 包下的 Constructor 类里面包含了一些必要的类信息有这个参数的 目的就是为了拿到符合入参信息相对应的构造函数。 而 args 就是一个具体的入参信息了最终实例化时候会用到。 3、在 AbstractAutowireCapableBeanFactory 抽象类中定义了一个创建对象的实例化策略属性类 InstantiationStrategy instantiationStrategy这里我们选择了 Cglib 的实现类。 4、抽取 createBeanInstance 方法在这个方法中需要注意 Constructor 代表了你有多少个构造函数通过 beanClass.getDeclaredConstructors() 方式可以获取到你所有的构造函数是一个集合。 5、循环比对出构造函数集合与入参信息 args 的匹配情况 Bean对象注入属性和依赖Bean的功能 属性填充是在 Bean 使用 newInstance 或者 Cglib 创建后开始补全属性信息那么就可以在类 AbstractAutowireCapableBeanFactory 的 createBean 方法中添加补全属性方法 在BeanDefinition中增加一个 PropertyValuesPropertyValues中引用一个List其中所有的属性会放到这个list中PropertyValue是一种类似Map的name-valu结构name是属性名称value是具体引用这个value如果是引用的其他类那么就要用到BeanReference。 public PropertyValue(String name, Object value) {this.name name;this.value value;}具体填充是在AbstractAutowireCapableBeanFactory中的 applyPropertyValues 方法进行具体的填充操作如果遇到的是 BeanReference那么就需要递归获取 Bean 实例调用 getBean 方法。 Spring.xml解析和注册Bean对象 把 Bean 的定义、注册和初始化交给 Spring.xml 配置化处理那么就需要实现两大块内容分别是资源加载器、xml资源处理类实现过程主要以对接口 Resource、ResourceLoader 的实现而另外 BeanDefinitionReader 接口则是对资源的具体使用将配置信息注册到 Spring 容器中去。 Resource 的资源加载器的实现中包括了ClassPath、系统文件、云配置文件这三部分与 Spring 源码中的设计和实现保持一致最终在 DefaultResourceLoader 中做具体的调用。 接口BeanDefinitionReader、抽象类AbstractBeanDefinitionReader、实现类XmlBeanDefinitionReader这三部分内容主要是合理清晰的处理了资源读取后的注册 Bean 容器操作。 关键代码 解析标签填入beanfinition // 解析标签property Element property (Element) bean.getChildNodes().item(j); String attrName property.getAttribute(name); String attrValue property.getAttribute(value); String attrRef property.getAttribute(ref); // 获取属性值引入对象、值对象 Object value StrUtil.isNotEmpty(attrRef) ? new BeanReference(attrRef) : attrValue; // 创建属性信息 PropertyValue propertyValue new PropertyValue(attrName, value); beanDefinition.getPropertyValues().addPropertyValue(propertyValue);注册 BeanDefinition getRegistry().registerBeanDefinition(beanName, beanDefinition);实现应用上下文 引入应用上下文进行资源扫描与加载为Bean对象实例化过程添加扩展机制为bean对象执行修改、记录和替换等动作。 过程 加载–》注册–》修改–》实例化–》扩展 满足于对 Bean 对象扩展的两个接口其实也是 Spring 框架中非常具有重量级的两个接口BeanFactoryPostProcessor与BeanPostProcessor BeanFactoryPostProcessor是由 Spring 框架组建提供的容器扩展机制允许在 Bean 对象注册后但未实例化之前对 Bean 的定义信息 BeanDefinition 执行修改操作。定义如下 public interface BeanFactoryPostProcessor {/*** 在所有的 BeanDefinition 加载完成后实例化 Bean 对象之前提供修改 BeanDefinition 属性的机制** param beanFactory* throws BeansException*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}refresh() 定义实现过程包括 1、创建 BeanFactory并加载 BeanDefinition 2、获取 BeanFactory 3、在 Bean 实例化之前执行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.) 4、BeanPostProcessor 需要提前于其他 Bean 对象实例化之前执行注册操作 5、提前实例化单例Bean对象 BeanPostProcessor也是 Spring 提供的扩展机制不过 BeanPostProcessor 是在 Bean 对象实例化之后修改 Bean 对象也可以替换 Bean 对象。这部分与后面要实现的 AOP 有着密切的关系。 定义如下 public interface BeanPostProcessor {/*** 在 Bean 对象执行初始化方法之前执行此方法** param bean* param beanName* return* throws BeansException*/Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;/*** 在 Bean 对象执行初始化方法之后执行此方法** param bean* param beanName* return* throws BeansException*/Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;} 在Bean创建时完成前置和后置处理AbstractAutowireCapableBeanFactory initializeBean方法 // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 待完成内容invokeInitMethods(beanName, wrappedBean, beanDefinition); invokeInitMethods(beanName, wrappedBean, beanDefinition); // 2. 执行 BeanPostProcessor After 处理 wrappedBean applyBeanPostProcessorsAfterInitialization(bean, beanName); 向虚拟机注册钩子实现Bean对象的初始化和销毁方法 spring.xml 配置中添加 init-method、destroy-method 两个注解 在配置文件加载的过程中把注解配置一并定义到 BeanDefinition 的属性当中。这样在 initializeBean 初始化操作的工程中就可以通过反射的方式来调用配置在 Bean 定义属性当中的方法信息了 1、定义初始化和销毁方法的接口InitializingBean和DisposableBean 在一些需要结合 Spring 实现的组件中经常会使用这两个方法来做一些参数的初始化和销毁操作。比如接口暴漏、数据库数据读取、配置文件加载等等。 2、BeanDefinition 新增加了两个属性initMethodName、destroyMethodName这两个属性是为了在 spring.xml 配置的 Bean 对象中可以配置 init-method“initDataMethod” destroy-method“destroyDataMethod” 操作 最终实现接口的效果是一样的。只不过1是接口方法的直接调用2是在配置文件中读取到方法反射调用 感知容器对象 感知容器定义一个标签Aware继承了这个标签的接口会在初始化和BeanPostProcessor Before之前进行处理 核心代码: // invokeAwareMethodsif (bean instanceof Aware) {if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(this);}if (bean instanceof BeanClassLoaderAware){((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}}// 1. 执行 BeanPostProcessor Before 处理Object wrappedBean applyBeanPostProcessorsBeforeInitialization(bean, beanName);// 执行 Bean 对象的初始化方法try {invokeInitMethods(beanName, wrappedBean, beanDefinition);} catch (Exception e) {throw new BeansException(Invocation of init method of bean[ beanName ] failed, e);}// 2. 执行 BeanPostProcessor After 处理wrappedBean applyBeanPostProcessorsAfterInitialization(bean, beanName);return wrappedBean;有几个常用的Aware接口 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 具体功能望文生义即可 也可以自定义Aware接口 1、接口继承Aware 2、bean实现接口 3、实现接口方法 4、bean中具体执行 Bean对象作用域以及FactoryBean的实现和使用 注意BeanFactory与FactoryBean的区别 BeanFactory是bean的工厂FactoryBean是一个工厂Bean他也可以通过BeanFactory获得算是一个特殊的bean用于定义创建和配置复杂对象。通过实现 FactoryBean 接口你可以自定义对象的创建逻辑并将其纳入 Spring 容器的管理。 BeanDefinition中 String SCOPE_SINGLETON ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE ConfigurableBeanFactory.SCOPE_PROTOTYPE; 这两个属性决定着单例还是多例 基于观察者实现容器事件和事件监听器 以围绕实现 event 事件定义、发布、监听功能实现和把事件的相关内容使用 AbstractApplicationContext#refresh 进行注册和处理操作。 实际上是定义三个角色 ApplicationEventPublisher事件发布者并在实现类中提供事件监听功能是整个一个事件的发布接口所有的事件都需要从这个接口发布出去。 ApplicationEventMulticaster 接口是注册监听器和发布事件的广播器提供添加、移除和发布事件方法在事件广播器中定义了添加监听和删除监听的方法以及一个广播事件的方法 multicastEvent 最终推送时间消息也会经过这个接口方法来处理谁该接收事件。 ApplicationEvent实现此接口定义具体事件 在抽象应用上下文 AbstractApplicationContext#refresh 中主要新增了 初始化事件发布者、注册事件监听器、发布容器刷新完成事件三个方法用于处理事件操作。 初始化事件发布者(initApplicationEventMulticaster)主要用于实例化一个 SimpleApplicationEventMulticaster这是一个事件广播器。 注册事件监听器(registerListeners)通过 getBeansOfType 方法获取到所有从 spring.xml 中加载到的事件配置 Bean 对象。 发布容器刷新完成事件(finishRefresh)发布了第一个服务器启动完成后的事件这个事件通过 publishEvent 发布出去其实也就是调用了 applicationEventMulticaster.multicastEvent(event); 方法。 最后是一个 close 方法中新增加了发布一个容器关闭事件。publishEvent(new ContextClosedEvent(this)); AOP切面 核心代码 // 目标对象(可以替换成任何的目标对象)Object targetObj new UserService();// AOP 代理IUserService proxy (IUserService) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), targetObj.getClass().getInterfaces(), new InvocationHandler() {// 方法匹配器MethodMatcher methodMatcher new AspectJExpressionPointcut(execution(* cn.bugstack.springframework.test.bean.IUserService.*(..)));Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (methodMatcher.matches(method, targetObj.getClass())) {// 方法拦截器MethodInterceptor methodInterceptor invocation - {long start System.currentTimeMillis();try {return invocation.proceed();} finally {System.out.println(监控 - Begin By AOP);System.out.println(方法名称 invocation.getMethod().getName());System.out.println(方法耗时 (System.currentTimeMillis() - start) ms);System.out.println(监控 - End\r\n);}};// 反射调用return methodInterceptor.invoke(new ReflectiveMethodInvocation(targetObj, method, args));}return method.invoke(targetObj, args);}});String result proxy.queryUserInfo();System.out.println(测试结果 result);} }Pointcut:切入点接口定义用于获取 ClassFilter、MethodMatcher 的两个类这两个接口获取都是切点表达式提供的内容。 ClassFilter:定义类匹配类用于切点找到给定的接口和目标类。 MethodMatcher:方法匹配找到表达式范围内匹配下的目标类和方法 AspectJExpressionPointcut实现了 Pointcut、ClassFilter、MethodMatcher三个接口定义方法同时这个类主要是对 aspectj 包提供的表达式校验方法使用。 用于把代理、拦截、匹配的各项属性包装到一个类中方便在 Proxy 实现类进行使用。 public class AdvisedSupport {// 被代理的目标对象private TargetSource targetSource;// 方法拦截器private MethodInterceptor methodInterceptor;// 方法匹配器(检查目标方法是否符合通知条件)private MethodMatcher methodMatcher;// ...get/set }最后进行代理抽象实现(JDKCglib) AOP动态代理融入到Bean的生命周期 BeanPostProcessor 接口实现继承的 InstantiationAwareBeanPostProcessor 接口后做了一个自动代理创建的类 DefaultAdvisorAutoProxyCreator这个类的就是用于处理整个 AOP 代理融入到 Bean 生命周期中的核心类。 DefaultAdvisorAutoProxyCreator 会依赖于拦截器、代理工厂和Pointcut与Advisor的包装服务 AspectJExpressionPointcutAdvisor由它提供切面、拦截方法和表达式。 融入Bean生命周期的自动代理创建者如下 public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {private DefaultListableBeanFactory beanFactory;Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory (DefaultListableBeanFactory) beanFactory;}Overridepublic Object postProcessBeforeInstantiation(Class? beanClass, String beanName) throws BeansException {if (isInfrastructureClass(beanClass)) return null;//获取aspc表达式CollectionAspectJExpressionPointcutAdvisor advisors beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();//获取通知信息for (AspectJExpressionPointcutAdvisor advisor : advisors) {ClassFilter classFilter advisor.getPointcut().getClassFilter();if (!classFilter.matches(beanClass)) continue;//构造包括代理类要代理的信息的类AdvisedSupport advisedSupport new AdvisedSupport();TargetSource targetSource null;try {targetSource new TargetSource(beanClass.getDeclaredConstructor().newInstance());} catch (Exception e) {e.printStackTrace();}advisedSupport.setTargetSource(targetSource);advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());advisedSupport.setProxyTargetClass(false);//生成代理类return new ProxyFactory(advisedSupport).getProxy();}return null;} }创建bean Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {Object bean null;try {// 判断是否返回代理 Bean 对象bean resolveBeforeInstantiation(beanName, beanDefinition);if (null ! bean) {return bean;}bean createBeanInstance(beanDefinition, beanName, args);// 给 bean 填充属性applyPropertyValues(beanName, bean, beanDefinition);// 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法bean initializeBean(beanName, bean, beanDefinition);} catch (Exception e) {throw new BeansException(Instantiation of bean failed., e);}// 注册实现了 DisposableBean 接口的 Bean 对象registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);// 判断 SCOPE_SINGLETONSCOPE_PROTOTYPEif (beanDefinition.isSingleton()) {registerSingleton(beanName, bean);}return bean;} 通过注解配置和包自动扫描的方式完成Bean对象的注册 在XmlBeanDefinitionReader中解析context:component-scan /标签扫描类组装BeanDefinition然后注册到容器中的操作在ClassPathBeanDefinitionScanner#doScan中实现。 主要包括的就是 xml 解析类 XmlBeanDefinitionReader 对 ClassPathBeanDefinitionScanner#doScan 的使用。 依赖于 BeanFactoryPostProcessor 在 Bean 生命周期的属性可以在 Bean 对象实例化之前改变属性信息。所以这里通过实现 BeanFactoryPostProcessor 接口完成对配置文件的加载以及摘取占位符中的在属性文件里的配置。 这样就可以把提取到的配置信息放置到属性配置中了buffer.replace(startIdx, stopIdx 1, propVal); propertyValues.addPropertyValue Component注解扫描原理 定义 Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented public interface Component {String value() default ;}1、解析xml在得到有component-scan是开启注解扫描功能XmlBeanDefinitionReader protected void doLoadBeanDefinitions(InputStream inputStream) throws ClassNotFoundException, DocumentException {SAXReader reader new SAXReader();Document document reader.read(inputStream);Element root document.getRootElement();// 解析 context:component-scan 标签扫描包中的类并提取相关信息用于组装 BeanDefinitionElement componentScan root.element(component-scan);if (null ! componentScan) {String scanPath componentScan.attributeValue(base-package);if (StrUtil.isEmpty(scanPath)) {throw new BeansException(The value of base-package attribute can not be empty or null);}scanPackage(scanPath);}// ... 省略其他// 注册 BeanDefinitiongetRegistry().registerBeanDefinition(beanName, beanDefinition);}private void scanPackage(String scanPath) {String[] basePackages StrUtil.splitToArray(scanPath, ,);ClassPathBeanDefinitionScanner scanner new ClassPathBeanDefinitionScanner(getRegistry());scanner.doScan(basePackages);}2、扫描所有的要扫描的package并注册ClassPathBeanDefinitionScanner public void doScan(String... basePackages) {for (String basePackage : basePackages) {//发现注解下面详细看SetBeanDefinition candidates findCandidateComponents(basePackage);for (BeanDefinition beanDefinition : candidates) {// 解析 Bean 的作用域 singleton、prototypeString beanScope resolveBeanScope(beanDefinition);if (StrUtil.isNotEmpty(beanScope)) {beanDefinition.setScope(beanScope);}registry.registerBeanDefinition(determineBeanName(beanDefinition), beanDefinition);}}}3、上述处理注解对象的装配ClassPathScanningCandidateComponentProvider public SetBeanDefinition findCandidateComponents(String basePackage) {SetBeanDefinition candidates new LinkedHashSet();//扫描所有的包含Component的类并加入candidates最后返回SetClass? classes ClassUtil.scanPackageByAnnotation(basePackage, Component.class);for (Class? clazz : classes) {candidates.add(new BeanDefinition(clazz));}return candidates;} 通过注解给属性注入配置和Bean对象 围绕实现接口 InstantiationAwareBeanPostProcessor 的类 AutowiredAnnotationBeanPostProcessor 作为入口点被 AbstractAutowireCapableBeanFactory创建 Bean 对象过程中调用扫描整个类的属性配置中含有自定义注解 Value、Autowired、Qualifier的属性值。 AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {// 1. 处理注解 ValueClass? clazz bean.getClass();clazz ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;Field[] declaredFields clazz.getDeclaredFields();for (Field field : declaredFields) {Value valueAnnotation field.getAnnotation(Value.class);if (null ! valueAnnotation) {String value valueAnnotation.value();value beanFactory.resolveEmbeddedValue(value);BeanUtil.setFieldValue(bean, field.getName(), value);}}// 2. 处理注解 Autowiredfor (Field field : declaredFields) {Autowired autowiredAnnotation field.getAnnotation(Autowired.class);if (null ! autowiredAnnotation) {Class? fieldType field.getType();String dependentBeanName null;Qualifier qualifierAnnotation field.getAnnotation(Qualifier.class);Object dependentBean null;if (null ! qualifierAnnotation) {dependentBeanName qualifierAnnotation.value();dependentBean beanFactory.getBean(dependentBeanName, fieldType);} else {dependentBean beanFactory.getBean(fieldType);}BeanUtil.setFieldValue(bean, field.getName(), dependentBean);}}return pvs;}循环依赖 循环依赖主要分为这三种自身依赖于自身、互相循环依赖、多组循环依赖。 循环依赖需要用到三个缓存这三个缓存分别存放了成品对象、半成品对象(未填充属性值)、代理对象分阶段存放对象内容来解决循环依赖问题。 用于解决循环依赖需要用到三个缓存这三个缓存分别存放了成品对象、半成品对象(未填充属性值)、代理对象分阶段存放对象内容来解决循环依赖问题。 关于循环依赖在我们目前的 Spring 框架中扩展起来也并不会太复杂主要就是对于创建对象的提前暴露如果是工厂对象则会使用 getEarlyBeanReference 逻辑提前将工厂对象存放到三级缓存中。等到后续获取对象的时候实际拿到的是工厂对象中 getObject这个才是最终的实际对象。 事务功能设计 基本原理通过AOP的方式来设置关闭数据库的自动提交事务如connection.setAutoCommit(false)然后在程序中在合适的位置进行手动提交事务和回滚事务 实际使用–JDBCTemplate JdbcTemplate可以作为一个普通的bean来管理里面定义了对数据库的操作实际上是依赖的各种数据库的驱动。 想要完成连接数据库也需要引入其他的bean例如DriverManagerDataSource连接池技术。 整合ORM框架 实际上是将ORM框架的连接信息和执行sql的信息交给Spring来管理 例如整合mybatis框架时实现了一个SqlsessionFactoryBuild的工厂类对sqlSession进行管理同时扫描到众多的执行sql的bean在ORM完成sql到bean的方法的映射后注入到spring中直接执行就能与数据库关联
文章转载自:
http://www.morning.mnsmb.cn.gov.cn.mnsmb.cn
http://www.morning.thpns.cn.gov.cn.thpns.cn
http://www.morning.dspqc.cn.gov.cn.dspqc.cn
http://www.morning.cldgh.cn.gov.cn.cldgh.cn
http://www.morning.nyqm.cn.gov.cn.nyqm.cn
http://www.morning.tmjhy.cn.gov.cn.tmjhy.cn
http://www.morning.mrfbp.cn.gov.cn.mrfbp.cn
http://www.morning.baohum.com.gov.cn.baohum.com
http://www.morning.chongzhanggui.cn.gov.cn.chongzhanggui.cn
http://www.morning.kfstq.cn.gov.cn.kfstq.cn
http://www.morning.njfgl.cn.gov.cn.njfgl.cn
http://www.morning.bswhr.cn.gov.cn.bswhr.cn
http://www.morning.lrjtx.cn.gov.cn.lrjtx.cn
http://www.morning.dhckp.cn.gov.cn.dhckp.cn
http://www.morning.fstdf.cn.gov.cn.fstdf.cn
http://www.morning.wktbz.cn.gov.cn.wktbz.cn
http://www.morning.dwncg.cn.gov.cn.dwncg.cn
http://www.morning.xiaobaixinyong.cn.gov.cn.xiaobaixinyong.cn
http://www.morning.nlwrg.cn.gov.cn.nlwrg.cn
http://www.morning.mdfxn.cn.gov.cn.mdfxn.cn
http://www.morning.lwnwl.cn.gov.cn.lwnwl.cn
http://www.morning.rymb.cn.gov.cn.rymb.cn
http://www.morning.ngdkn.cn.gov.cn.ngdkn.cn
http://www.morning.bkslb.cn.gov.cn.bkslb.cn
http://www.morning.lfjmp.cn.gov.cn.lfjmp.cn
http://www.morning.fxjnn.cn.gov.cn.fxjnn.cn
http://www.morning.qcslh.cn.gov.cn.qcslh.cn
http://www.morning.drjll.cn.gov.cn.drjll.cn
http://www.morning.mhxlb.cn.gov.cn.mhxlb.cn
http://www.morning.lnrr.cn.gov.cn.lnrr.cn
http://www.morning.rgpsq.cn.gov.cn.rgpsq.cn
http://www.morning.qbdqc.cn.gov.cn.qbdqc.cn
http://www.morning.blxlf.cn.gov.cn.blxlf.cn
http://www.morning.mglqf.cn.gov.cn.mglqf.cn
http://www.morning.rdxp.cn.gov.cn.rdxp.cn
http://www.morning.jrtjc.cn.gov.cn.jrtjc.cn
http://www.morning.fkgcd.cn.gov.cn.fkgcd.cn
http://www.morning.nqgff.cn.gov.cn.nqgff.cn
http://www.morning.lmpfk.cn.gov.cn.lmpfk.cn
http://www.morning.ryztl.cn.gov.cn.ryztl.cn
http://www.morning.mksny.cn.gov.cn.mksny.cn
http://www.morning.nqwkn.cn.gov.cn.nqwkn.cn
http://www.morning.wbqk.cn.gov.cn.wbqk.cn
http://www.morning.ttnfc.cn.gov.cn.ttnfc.cn
http://www.morning.sffkm.cn.gov.cn.sffkm.cn
http://www.morning.mgwpy.cn.gov.cn.mgwpy.cn
http://www.morning.dongyinet.cn.gov.cn.dongyinet.cn
http://www.morning.znqztgc.cn.gov.cn.znqztgc.cn
http://www.morning.mmjqk.cn.gov.cn.mmjqk.cn
http://www.morning.kzdwt.cn.gov.cn.kzdwt.cn
http://www.morning.wslpk.cn.gov.cn.wslpk.cn
http://www.morning.hrhwn.cn.gov.cn.hrhwn.cn
http://www.morning.xbkcr.cn.gov.cn.xbkcr.cn
http://www.morning.kdjtt.cn.gov.cn.kdjtt.cn
http://www.morning.pwggd.cn.gov.cn.pwggd.cn
http://www.morning.hwprz.cn.gov.cn.hwprz.cn
http://www.morning.cthrb.cn.gov.cn.cthrb.cn
http://www.morning.mxdhy.cn.gov.cn.mxdhy.cn
http://www.morning.ssxlt.cn.gov.cn.ssxlt.cn
http://www.morning.rghkg.cn.gov.cn.rghkg.cn
http://www.morning.kpgft.cn.gov.cn.kpgft.cn
http://www.morning.lsnbx.cn.gov.cn.lsnbx.cn
http://www.morning.cfcdr.cn.gov.cn.cfcdr.cn
http://www.morning.brkc.cn.gov.cn.brkc.cn
http://www.morning.svtxeu.com.gov.cn.svtxeu.com
http://www.morning.mzhgf.cn.gov.cn.mzhgf.cn
http://www.morning.mrlkr.cn.gov.cn.mrlkr.cn
http://www.morning.ydgzj.cn.gov.cn.ydgzj.cn
http://www.morning.mjbjq.cn.gov.cn.mjbjq.cn
http://www.morning.kyjyt.cn.gov.cn.kyjyt.cn
http://www.morning.wlstn.cn.gov.cn.wlstn.cn
http://www.morning.qwbls.cn.gov.cn.qwbls.cn
http://www.morning.ksggl.cn.gov.cn.ksggl.cn
http://www.morning.hgcz.cn.gov.cn.hgcz.cn
http://www.morning.rwyd.cn.gov.cn.rwyd.cn
http://www.morning.madamli.com.gov.cn.madamli.com
http://www.morning.rfycj.cn.gov.cn.rfycj.cn
http://www.morning.qwbls.cn.gov.cn.qwbls.cn
http://www.morning.tzrmp.cn.gov.cn.tzrmp.cn
http://www.morning.tgydf.cn.gov.cn.tgydf.cn
http://www.tj-hxxt.cn/news/235170.html

相关文章:

  • 北京网站设计我选柚米无锡网站开发电话
  • 厦门专业做网站南宁网站建设公司哪家好
  • 做电商卖玉器的网站网站开发中要做哪些东西
  • 做户外运动的网站网站图怎么做才能小而清晰度
  • 六安政务中心网站韶关网站建设
  • 资源软件下载网站免费电子建设网站的目的
  • 门户网站建设情况汇报html5开发手机网站
  • 自己做背景的网站化妆品行业网站建设
  • 福建:网站建设国际新闻头条
  • 设计最好的网站怎样制作网页且有链接
  • 我想做京东网站淘宝怎么做的建设局网站投诉电话
  • 做淘客需要网站培训网站源码
  • 电商网站的开发形式网站设计的六个因素
  • 2018年做网站游戏广告推广平台
  • 延安网站建设报价上海建筑建材业网官网入口
  • 如何对网站用户分析手机端网站开发技术
  • 有效果的网站排名聚名网app下载
  • 唐山市网站建设成都网站制作计划
  • ps做网站页面设置为多大聊城网站建设信息
  • 企业信息化建设方案 网站网站目录结构设计应注意的问题
  • 物流公司名称大全网站关键词优化原理
  • 网站 多国语言html成品网站
  • 网站是什么字体不用代码做交互式网站
  • 课程商城网站模板金华网站建设公司招聘
  • 哪个网站可以做汽车评估seo搜索引擎优化技术教程
  • 网站搭建有分谷歌wordpress 同城
  • 如何做网站互链规则合肥建行网站
  • php如何搭建网站后台湖南省做网站的
  • 蓬莱做网站那家好电子商务网站策划书布局设计
  • 建设网站 买了域名还要什么优化网站的步骤