【GTD源码】【php排盘 源码】【chroma MES系统源码】Configuration源码

来源:鸿蒙源码剖析

1.Spring5源码分析之@Configuration注解的详解。希望读者能够耐着性子看完
2.Spring Configuration:@Import的用法和源码解析
3.c#读取Config文件的问题
4.@Bean注解源码分析
5.Spring注解配置:@Configuration 和 @Component 区别及原理详解

Configuration源码

Spring5源码分析之@Configuration注解的详解。希望读者能够耐着性子看完

       Spring5源码中@Configuration注解详解,让你理解无需XML的Bean创建。在Spring 3.0以后,@Configuration注解的GTD源码出现,允许开发者在运行时动态创建和初始化Bean,无需依赖XML配置。它实际上标记了@Component元注解,被@ComponentScan扫描并纳入Spring容器管理。

       使用@Configuration时,Bean的默认名称与方法名称相同,可通过name属性指定。它不仅自身可以作为受管理的组件,还能通过@Autowired和@Inject注解注入其他Bean。例如,修改Demo,配置类可以作为服务组件被自动扫描。

       @Configuration不仅支持@ComponentScan,还能与@Controller、@Service、@Repository等注解配合,这些注解本质上都有@Component,适合不同场景的管理。此外,php排盘 源码@Configuration可以同@Import和@Profile注解组合,实现更灵活的配置导入和环境条件控制。

       在配置类内部嵌套@Configuration,可以利用静态内部类简化@Import的使用。配置类的初始化可以通过@Lazy注解延迟,提供更细致的控制。配置类解析涉及@ConfigurationClassPostProcessor处理器,处理@Configuration类的@Bean、@ComponentScan和环境相关注解。

       最后,@Configuration类的Bean定义信息由ConfigurationClassBeanDefinitionReader处理并注册到Spring容器,整个过程包括解析@Configuration类、扫描相关注解和Bean定义的加载。

       理解@Configuration的解析流程,能帮助你更高效地利用Spring的动态配置能力。如果你对文章内容有所收获,别忘了分享和关注我们的更多内容。

Spring Configuration:@Import的用法和源码解析

       Spring 3.0之后的@Configuration注解和注解配置体系替代了XML配置,本文主要讲解@Import的用法和源码解析。

       @Import的用法

       配置类(带有@Configuration注解)不仅可通过@Bean声明bean,还可通过@Import导入其他类。例如,WebMvcConfig类通过@Import导入其他配置类,同时启用@EnableWebMvc。chroma MES系统源码

       直接导入

       配置类上使用@Import可以导入一个或多个类,甚至可以出现在父类注解中。如WebMvcConfig导入DelegatingWebMvcConfiguration等。

       ImportBeanDefinitionRegistrar和ImportSelector

       @Import除了导入配置类,还可以导入实现了ImportBeanDefinitionRegistrar(如@EnableAspectJAutoProxy)和ImportSelector(如@EnableTransactionManagement)的类。

       源码解析

       ConfigurationClassPostProcessor负责处理@Configuration类,通过ConfigurationClassParser解析配置和导入,由ConfigurationClassBeanDefinitionReader注册BeanDefinition。在解析过程中,处理@Import避免循环导入,通过导入链和ImportStack进行判断。

       处理直接导入时,通过导入链判断循环。

       处理注册器和选择器时,提前触发Aware接口方法,然后在适当时机注册导入的类。

       总结来说,@Import提供了多种导入方式的灵活性,Spring的源码设计考虑了循环导入和重复解析的处理,展示了其强大的自定义配置能力。

c#读取Config文件的问题

       应用程序配置文件(App.config)是标准的 XML 文件,XML 标记和属性是区分大小写的。它是可以按需要更改的,开发人员可以使用配置文件来更改设置,zedboard官方源码教程而不必重编译应用程序。

       对于一个config文件:

       <?xml version="1.0" encoding="utf-8" ?>

       <configuration>

        <appSettings>

        <add key="ServerIP" value=".0.0.1"></add>

        <add key="DataBase" value="WarehouseDB"></add>

        <add key="user" value="sa"></add>

        <add key="password" value="sa"></add>

        </appSettings>

       </configuration>

       对config配置文件的读写类:

       using System;

       using System.Collections.Generic;

       using System.Linq;

       using System.Text;

       using System.Text.RegularExpressions;

       using System.Configuration;

       using System.ServiceModel;

       using System.ServiceModel.Configuration;

       namespace NetUtilityLib

       {

        public static class ConfigHelper

        {

        //依据连接串名字connectionName返回数据连接字符串

        public static string GetConnectionStringsConfig(string connectionName)

        {

        //指定config文件读取

        string file = System.Windows.Forms.Application.ExecutablePath;

        System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(file);

        string connectionString =

        config.ConnectionStrings.ConnectionStrings[connectionName].ConnectionString.ToString();

        return connectionString;

        }

        ///<summary>

        ///更新连接字符串

        ///</summary>

        ///<param name="newName">连接字符串名称</param>

        ///<param name="newConString">连接字符串内容</param>

        ///<param name="newProviderName">数据提供程序名称</param>

        public static void UpdateConnectionStringsConfig(string newName, string newConString, string newProviderName)

        {

        //指定config文件读取

        string file = System.Windows.Forms.Application.ExecutablePath;

        Configuration config = ConfigurationManager.OpenExeConfiguration(file);

        bool exist = false; //记录该连接串是否已经存在

        //如果要更改的连接串已经存在

        if (config.ConnectionStrings.ConnectionStrings[newName] != null)

        {

        exist = true;

        }

        // 如果连接串已存在,首先删除它

        if (exist)

        {

        config.ConnectionStrings.ConnectionStrings.Remove(newName);

        }

        //新建一个连接字符串实例

        ConnectionStringSettings mySettings =

        new ConnectionStringSettings(newName, newConString, newProviderName);

        // 将新的连接串添加到配置文件中.

        config.ConnectionStrings.ConnectionStrings.Add(mySettings);

        // 保存对配置文件所作的更改

        config.Save(ConfigurationSaveMode.Modified);

        // 强制重新载入配置文件的ConnectionStrings配置节

        ConfigurationManager.RefreshSection("ConnectionStrings");

        }

        ///<summary>

        ///返回*.exe.config文件中appSettings配置节的value项

        ///</summary>

        ///<param name="strKey"></param>

        ///<returns></returns>

        public static string GetAppConfig(string strKey)

        {

        string file = System.Windows.Forms.Application.ExecutablePath;

        Configuration config = ConfigurationManager.OpenExeConfiguration(file);

        foreach (string key in config.AppSettings.Settings.AllKeys)

        {

        if (key == strKey)

        {

        return config.AppSettings.Settings[strKey].Value.ToString();

        }

        }

        return null;

        }

        ///<summary>

        ///在*.exe.config文件中appSettings配置节增加一对键值对

        ///</summary>

        ///<param name="newKey"></param>

        ///<param name="newValue"></param>

        public static void UpdateAppConfig(string newKey, string newValue)

        {

        string file = System.Windows.Forms.Application.ExecutablePath;

        Configuration config = ConfigurationManager.OpenExeConfiguration(file);

        bool exist = false;

        foreach (string key in config.AppSettings.Settings.AllKeys)

        {

        if (key == newKey)

        {

        exist = true;

        }

        }

        if (exist)

        {

        config.AppSettings.Settings.Remove(newKey);

        }

        config.AppSettings.Settings.Add(newKey, newValue);

        config.Save(ConfigurationSaveMode.Modified);

        ConfigurationManager.RefreshSection("appSettings");

        }

        // 修改system.serviceModel下所有服务终结点的IP地址

        public static void UpdateServiceModelConfig(string configPath, string serverIP)

        {

        Configuration config = ConfigurationManager.OpenExeConfiguration(configPath);

        ConfigurationSectionGroup sec = config.SectionGroups["system.serviceModel"];

        ServiceModelSectionGroup serviceModelSectionGroup = sec as ServiceModelSectionGroup;

        ClientSection clientSection = serviceModelSectionGroup.Client;

        foreach (ChannelEndpointElement item in clientSection.Endpoints)

        {

        string pattern = @"\b\d{ 1,3}\.\d{ 1,3}\.\d{ 1,3}\.\d{ 1,3}\b";

        string address = item.Address.ToString();

        string replacement = string.Format("{ 0}", serverIP);

        address = Regex.Replace(address, pattern, replacement);

        item.Address = new Uri(address);

        }

        config.Save(ConfigurationSaveMode.Modified);

        ConfigurationManager.RefreshSection("system.serviceModel");

        }

        // 修改applicationSettings中App.Properties.Settings中服务的IP地址

        public static void UpdateConfig(string configPath, string serverIP)

        {

        Configuration config = ConfigurationManager.OpenExeConfiguration(configPath);

        ConfigurationSectionGroup sec = config.SectionGroups["applicationSettings"];

        ConfigurationSection configSection = sec.Sections["DataService.Properties.Settings"];

        ClientSettingsSection clientSettingsSection = configSection as ClientSettingsSection;

        if (clientSettingsSection != null)

        {

        SettingElement element1 = clientSettingsSection.Settings.Get("DataService_SystemManagerWS_SystemManagerWS");

        if (element1 != null)

        {

        clientSettingsSection.Settings.Remove(element1);

        string oldValue = element1.Value.ValueXml.InnerXml;

        element1.Value.ValueXml.InnerXml = GetNewIP(oldValue, serverIP);

        clientSettingsSection.Settings.Add(element1);

        }

        SettingElement element2 = clientSettingsSection.Settings.Get("DataService_EquipManagerWS_EquipManagerWS");

        if (element2 != null)

        {

        clientSettingsSection.Settings.Remove(element2);

        string oldValue = element2.Value.ValueXml.InnerXml;

        element2.Value.ValueXml.InnerXml = GetNewIP(oldValue, serverIP);

        clientSettingsSection.Settings.Add(element2);

        }

        }

        config.Save(ConfigurationSaveMode.Modified);

        ConfigurationManager.RefreshSection("applicationSettings");

        }

        private static string GetNewIP(string oldValue, string serverIP)

        {

        string pattern = @"\b\d{ 1,3}\.\d{ 1,3}\.\d{ 1,3}\.\d{ 1,3}\b";

        string replacement = string.Format("{ 0}", serverIP);

        string newvalue = Regex.Replace(oldValue, pattern, replacement);

        return newvalue;

        }

        }

       }

       测试代码如下:

        class Program

        {

        static void Main(string[] args)

        {

        try

        {

        //string file = System.Windows.Forms.Application.ExecutablePath + ".config";

        //string file1 = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

        string serverIP = ConfigHelper.GetAppConfig("ServerIP");

        string db = ConfigHelper.GetAppConfig("DataBase");

        string user = ConfigHelper.GetAppConfig("user");

        string password = ConfigHelper.GetAppConfig("password");

        Console.WriteLine(serverIP);

        Console.WriteLine(db);

        Console.WriteLine(user);

        Console.WriteLine(password);

        ConfigHelper.UpdateAppConfig("ServerIP", "..1.");

        string newIP = ConfigHelper.GetAppConfig("ServerIP");

        Console.WriteLine(newIP);

        Console.ReadKey();

        }

        catch (Exception ex)

        {

        Console.WriteLine(ex.Message);

        }

        }

        }

@Bean注解源码分析

       ✒️作者 - Lex 博客 - 我的CSDN 文章目录 - 所有文章 源码地址 - @Bean源码

       @Bean是Spring框架的核心注解,用于标记一个方法,表明该方法返回值应被注册为Spring容器中的一个对象(Bean)。与传统的XML配置方式相比,它提供了一种更为简洁和直观的方式来定义Bean。通常,@Bean与@Configuration注解一起使用,后者标记一个类为Spring的配置类。方法名默认作为Bean的ID,但也可通过@Bean的name属性自定义。这种声明式的Bean定义方式在Java代码中提供了强大的灵活性,允许利用Java的完整特性来配置和初始化对象。结合其他Spring特性如@Autowired,可以轻松实现依赖注入,进一步简化应用的配置和组件管理。通过@Bean注解,Spring为现代化应用开发提供了强大的支持,使代码更为整洁和易于维护。

       @Bean注解是Spring框架自3.0版本开始引入的一个核心注解,表明一个方法会返回一个对象,该对象应被注册为Spring应用上下文中的一个bean。

       主要功能包括:标记一个方法作为Bean的优化EXPMA公式源码定义,方法返回值即为注册的bean;允许自定义bean的ID;支持依赖注入,通过@Autowired实现;提供生命周期方法,如initMethod和destroyMethod。

       最佳实践:在启动类入口使用AnnotationConfigApplicationContext配置Spring容器,提供配置类作为参数;在配置类中使用@Bean注解定义bean;确保在initMethod中初始化bean,在destroyMethod中清理资源;利用@Configuration注解标记配置类。

       源码分析涉及启动类初始化流程、bean的实例化、初始化和销毁过程。重点关注Spring容器的初始化、bean定义的加载、实例化、初始化和销毁等关键步骤。

       注意事项包括:确保配置类和方法符合注解要求;合理使用生命周期方法;正确处理依赖关系。

       总结:@Bean注解简化了Bean的定义过程,提供了强大的灵活性和可维护性,是构建现代Spring应用的关键工具。通过深入理解其源码和最佳实践,开发者可以更高效地利用Spring框架,构建高效、可扩展的应用。

Spring注解配置:@Configuration 和 @Component 区别及原理详解

       随着Spring Boot的盛行,注解配置式开发得到了广泛应用,使我们能够通过简洁的代码实现复杂的配置。Spring内部定义了如@Component、@Configuration、@Bean、@Import等配置注解,它们各自负责不同的功能,但本质上都被Spring作为配置注解进行处理。注解如@Component与@Configuration是我们在日常开发中经常用到的,接下来我们来探讨它们的区别及原理。

       在Spring框架的发展过程中,配置方式从原始的XML配置逐渐发展到当前的自动化装配阶段,Spring在其中发挥了巨大作用。从最初的XML配置,到后来的自动装配、从Spring到Spring Boot,再到引入如@Conditional等注解,Spring不断进化,使配置变得越来越简单、智能。在Spring的配置管理中,关键在于如何将复杂的配置细节隐藏,使得开发者能够更加专注于业务逻辑的开发。今天,我们就来深入了解@Component与@Configuration的区别及原理。

       在Spring开发中,使用配置注解是很常见的做法,其中@Component与@Configuration是最常用的两种。然而,除了它们之外,Spring还支持使用其他的注解标记类为配置类。在这里,我们将重点讨论@Component与@Configuration,因为它们与我们的日常开发工作联系最为紧密。接下来,让我们探讨一下这两个注解的主要区别。

       在开发实践中,我们可以使用@Component或@Configuration来标记类作为配置类。然而,它们之间存在一些显著的区别,尤其是关于它们的代理机制。接下来,我们将详细讨论这些区别及原因。

       在Spring中,注解与配置之间的关系十分密切。理解注解的意义与用途有助于我们更好地利用Spring框架,实现高效、灵活的开发过程。为了更直观地理解@Component与@Configuration的区别,我们将从定义、使用场景、代理机制等方面进行深入探讨。

       在深入分析之前,我们先明确一个概念:Spring中的配置类可以分为“轻量级”(LITE)与“全面型”(FULL)两种类型,而@Component与@Configuration分别对应这两种配置类型。接下来,我们将通过具体的代码示例来阐述它们之间的区别。

       当我们使用@Component注解来标记一个类作为配置类时,Spring会将该类视为轻量级配置类。这意味着,当该类中的@Bean方法被调用时,方法间的相互调用遵循普通Java类的方法调用规则。然而,当使用@Configuration注解时,情况会有所不同。在这种情况下,Spring会将该类视为全面型配置类,这意味着它会为该类中的@Bean方法提供代理机制,确保方法间的相互调用能够正确执行。

       了解了这两种配置类的区别之后,我们来详细探讨它们的实现原理。在深入分析之前,让我们首先了解Spring内部实现这些配置注解的关键类:ConfigurationClassPostProcessor。这个类在Spring中扮演着至关重要的角色,负责将配置类转换为相应的配置结构。

       ConfigurationClassPostProcessor是一个BeanDefinitionRegistryPostProcessor,这意味着它在Spring容器初始化时自动被激活。通过一系列的方法调用,它能够解析配置类中的注解信息,并将这些信息转换为具体的BeanDefinition。接下来,我们将深入探讨ConfigurationClassPostProcessor是如何实现这种转换的。

       为了理解ConfigurationClassPostProcessor的工作原理,我们需要明确它在Spring容器初始化过程中的角色。通过分析源代码,我们可以发现,ConfigurationClassPostProcessor在Spring容器初始化时就已经被注册为BeanDefinition的处理者。接下来,它将通过一系列的方法调用,完成对配置类的解析、转换,并最终将这些信息注册为Spring容器中的Bean。

       通过深入分析ConfigurationClassPostProcessor的关键方法,我们可以发现,它主要完成了对注解的解析、BeanDefinition的生成以及代理机制的实现。具体而言,它通过检查配置类的注解信息,判断其是否属于轻量级或全面型配置类,并根据不同的类型采取相应的处理策略。例如,当配置类被标记为全面型时,Spring会使用CGLIB进行代理,确保方法间的调用能够正确执行。

       综上所述,@Component注解标记的配置类在Spring中被视为轻量级配置类,它适用于方法间的简单调用;而@Configuration注解标记的配置类被视为全面型配置类,它支持更复杂的依赖注入和方法间调用。在理解了这些基本原理之后,我们能够更高效地利用Spring框架进行开发,实现更灵活、更强大的应用。

文章所属分类:休闲频道,点击进入>>