Application初始化

本文详细介绍了Spring框架中的两种核心容器BeanFactory与ApplicationContext的使用方法,包括不同方式的配置文件加载、资源定位及多文件加载等高级用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BeanFactory有很多实现类,通常使用org.springframework.beans.factory.xml.XmlBeanFactory类。但对于大部分J2EE应用而言,推荐使用ApplicationContext. ApplicationContext是 

BeanFactory的子接口,其常用实现类是org.springframework.context.support.FileSystemXmlApplicationContext和org.springframework.context.support.ClassXmlAplicationContext。 
Springr的配置信息通常采用XML配置文件来设置,因此,创建BeanFactory实例时,应该提供XML配置文件作为参数。、 

下面详细介绍ApplicationContext的实际运用: 



一:ClassPathXmlApplicationContext 
1.没有前缀:默认为项目的classpath下相对路径 
   ApplicationContext appCt = new ClassPathXmlApplicationContext("app.spring.xml"); 

2.前缀classpath:表示的是项目的classpath下相对路径 
   ApplicationContext appCt = new ClassPathXmlApplicationContext("classpath:app.spring.xml"); 

3.使用前缀file 表示的是文件的绝对路径 
   ApplicationContext appCt = new ClassPathXmlApplicationContext("file:D:/app.spring.xml"); 

4.可以同时加载多个文件 
  String[] xmlCfg = new String[] { "classpath:base.spring.xml","app.spring.xml"}; 
  ApplicationContext appCt = new ClassPathXmlApplicationContext(xmlCfg); 

5.使用通配符加载所有符合要求的文件 
  ApplicationContext appCt = new ClassPathXmlApplicationContext("*.spring.xml"); 

二:FileSystemXmlApplicationContext 
1.默认为项目工作路径 即项目的根目录 
ApplicationContext appCt2 = new FileSystemXmlApplicationContext("src/main/resources/app.spring.xml"); 

2.前缀classpath:表示的是项目的classpath下相对路径 
   ApplicationContext appCt2 = new FileSystemXmlApplicationContext("classpath:app.spring.xml"); 

3.使用前缀file 表示的是文件的绝对路径 
   ApplicationContext appCt2 = new FileSystemXmlApplicationContext("file:D:/app.spring.xml"); 
   ApplicationContext appCt2 = new FileSystemXmlApplicationContext("D:/app.spring.xml"); 

4.可以同时加载多个文件 
  String[] xmlCfg = new String[] { "src/main/resources/base.spring.xml","classpath:app.spring.xml"}; 
  ApplicationContext appCt2 = new FileSystemXmlApplicationContext(xmlCfg); 

5.使用通配符加载所有符合要求的文件 
  ApplicationContext appCt2 = new FileSystemXmlApplicationContext("classpath:*.spring.xml"); 


6.Resource 

ResourcePatternResolver     resolver=new PathmatchingResourceResolver(); 
Resource   res = resolver.getResource("classpath:com/hh/beans.xml"); 
Beanfactory    bf = new  XmlBeanFactory(res); 
Car  car= bf.getBean("car",Car.class) 

<think>我们参考用户提供的引用和之前的问题,来回答关于Android应用级别(Application级别)初始化和资源释放的方法。 用户引用[1]提到:在宿主应用的Application类的onCreate方法中初始化DroidPlugin,设置参数等。 用户引用[2]提到:可以通过自定义初始化模块,并按照顺序执行初始化操作。 用户引用[3]提到:Application的onCreate()方法在应用启动时调用,适合全局初始化;onTerminate()方法在应用退出时调用,但大部分设备上不会调用。 用户引用[4]展示了一个模块化初始化的例子,通过反射创建各个子模块的初始化类对象,并调用其初始化方法,分为高优先级和低优先级。 结合用户之前的问题,我们总结如下: 一、Application级别的初始化: 1. 创建自定义Application类(继承Application)。 2. 在AndroidManifest.xml中声明自定义Application类。 3. 在自定义Application类的onCreate()方法中执行初始化操作。 初始化操作可以包括: - 初始化第三方库(如DroidPlugin、网络库、数据库等)。 - 设置全局配置(如日志级别、存储路径等)。 - 进行模块化初始化(通过反射或依赖注入按优先级初始化各模块)。 二、Application级别的资源释放: 1. 注意:Application的onTerminate()方法在真实设备上通常不会被调用(仅模拟器可能调用),因此不能依赖它来释放资源。 2. 替代方案:对于需要释放的资源(如数据库连接、线程池等),可以设计为在不需要时自行释放,或者使用单例模式并在适当的时机(如应用退出前)主动调用释放方法。但通常,系统会在应用进程终止时自动回收资源,所以我们主要关注可能泄漏的资源(如静态引用、未关闭的数据库连接等)的主动释放。 三、模块化初始化的实现: 我们可以设计一个初始化接口(如BaseAppInit),各个模块实现该接口,并定义高优先级和低优先级的初始化方法。 然后在Application的onCreate()中,通过反射或依赖注入的方式,按顺序调用这些初始化方法。 四、代码示例: 步骤1:定义初始化接口 ```java public interface BaseAppInit { // 高优先级初始化(例如:需要在其他初始化之前完成的) void onInitHighPriority(Application app); // 低优先级初始化 void onInitLowPriority(Application app); } ``` 步骤2:各个模块实现该接口(例如:日志模块、网络模块等) ```java public class LogInit implements BaseAppInit { @Override public void onInitHighPriority(Application app) { // 初始化日志系统 LogManager.init(app); } @Override public void onInitLowPriority(Application app) { // 可以留空,或者执行日志模块的低优先级初始化 } } ``` 步骤3:在Application中按顺序初始化 ```java public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); // 先执行高优先级初始化 initModuleHighPriority(); // 执行其他全局初始化(如第三方库) // ... // 最后执行低优先级初始化 initModuleLowPriority(); } private void initModuleHighPriority() { // 从配置中获取所有需要初始化的模块类名 for (String className : ModuleConfig.HIGH_PRIORITY_INITS) { try { Class<?> clazz = Class.forName(className); BaseAppInit init = (BaseAppInit) clazz.newInstance(); init.onInitHighPriority(this); } catch (Exception e) { e.printStackTrace(); } } } private void initModuleLowPriority() { for (String className : ModuleConfig.LOW_PRIORITY_INITS) { try { Class<?> clazz = Class.forName(className); BaseAppInit init = (BaseAppInit) clazz.newInstance(); init.onInitLowPriority(this); } catch (Exception e) { e.printStackTrace(); } } } } ``` 注意:ModuleConfig中定义了模块初始化类的全名列表。 五、资源释放的替代方案: 由于不能依赖onTerminate(),我们可以考虑以下方式: 1. 对于需要释放的资源,在单例对象中提供释放方法,并在适当的时机(如应用退出前)调用。但应用退出的时机很难捕获。 2. 使用WeakReference或SoftReference来持有资源,让系统在内存不足时回收。 3. 对于数据库连接、文件流等,确保在使用后及时关闭(例如在Service或Activity中及时关闭),避免在Application中持有需要释放的资源。 六、注意事项: 1. 避免在Application的onCreate()中执行耗时操作,以防ANR。 2. 初始化顺序很重要,因此模块化初始化时要注意优先级。 综上所述,Application级别的初始化主要在onCreate()中完成,而资源释放则不能依赖onTerminate(),需要设计合理的释放机制。 相关问题: 1. 如何避免Application中的内存泄漏? 2. 模块化初始化有什么优势? 3. 除了反射,还有其他方式实现模块化初始化吗?</think>### Android Application级别初始化和资源释放方法 #### 一、初始化操作(在Application.onCreate()中执行) ```java public class MyApp extends Application { private static final String TAG = "MyApp"; @Override public void onCreate() { super.onCreate(); // 1. 初始化第三方库 DroidPlugin.initialize(this, new PluginConfig() .setPluginPath("/sdcard/plugins") .setLogLevel(LogLevel.DEBUG)); // 引用[1] // 2. 模块化初始化(高优先级) initModuleHighPriority(); // 引用[4] // 3. 初始化全局单例 DatabaseManager.init(this); AnalyticsService.setup(this); // 4. 模块化初始化(低优先级) initModuleLowPriority(); // 引用[4] // 5. 全局配置加载 ConfigLoader.loadGlobalConfig(); } private void initModuleHighPriority() { for (String module : ModuleConfig.HIGH_PRIORITY_MODULES) { try { BaseAppInit init = (BaseAppInit) Class.forName(module).newInstance(); init.onInitHighPriority(this); // 引用[2] } catch (Exception e) { Log.e(TAG, "HighPriority init failed: " + module, e); } } } private void initModuleLowPriority() { for (String module : ModuleConfig.LOW_PRIORITY_MODULES) { try { BaseAppInit init = (BaseAppInit) Class.forName(module).newInstance(); init.onInitLowPriority(this); // 引用[2] } catch (Exception e) { Log.e(TAG, "LowPriority init failed: " + module, e); } } } } ``` #### 二、资源释放操作 ```java public class MyApp extends Application { // ... @Override public void onTerminate() { // 注意:真机上不一定调用,仅作最终清理 releaseResources(); super.onTerminate(); // 引用[3] } @Override public void onLowMemory() { super.onLowMemory(); // 内存不足时释放非关键资源 ImageCache.clear(); } @Override public void onTrimMemory(int level) { super.onTrimMemory(level); if (level >= TRIM_MEMORY_MODERATE) { releaseNonCriticalResources(); } } private void releaseResources() { // 1. 关闭数据库连接 DatabaseManager.close(); // 2. 释放第三方库资源 DroidPlugin.release(); // 3. 停止后台服务 AnalyticsService.shutdown(); } private void releaseNonCriticalResources() { // 释放可重建的缓存 TempDataCache.clear(); PreviewImageCache.clear(); } } ``` #### 三、最佳实践要点 1. **初始化顺序控制**: - 使用`getOrder()`方法定义模块初始化顺序(引用[2]) - 高优先级模块先初始化(如网络库、安全模块) - 低优先级模块后初始化(如UI组件、辅助工具) 2. **模块化设计**: ```java public interface BaseAppInit { void onInitHighPriority(Application app); void onInitLowPriority(Application app); default int getOrder() { return 0; } // 引用[2] } // 示例模块实现 public class NetworkModule implements BaseAppInit { @Override public void onInitHighPriority(Application app) { OkHttpClient.setup(app); } @Override public int getOrder() { return 10; } // 数值越小优先级越高 } ``` 3. **资源释放策略**: - 关键资源在`onTerminate()`释放(但不可依赖) - 非关键资源在`onTrimMemory()`释放 - 使用`WeakReference`管理缓存对象 - 单例对象提供`release()`方法 4. **注意事项**: - 避免在`onCreate()`执行耗时操作(>5秒可能触发ANR) - 使用`StrictMode`检测主线程违规操作 - 真机环境`onTerminate()`调用不可靠(引用[3]),需设计主动释放机制 - 模块初始化异常应捕获并记录,避免崩溃 #### 四、配置声明(AndroidManifest.xml) ```xml <application android:name=".MyApp" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" ...> </application> ``` > **设计建议**:对于大型项目,推荐使用启动优化库(如App Startup)管理初始化顺序和线程分配,避免主线程阻塞[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值