【Java万花筒】解析Java依赖注入:从Spring到CDI的全方位比较

2024-02-14 22:28

本文主要是介绍【Java万花筒】解析Java依赖注入:从Spring到CDI的全方位比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

探索Java依赖注入:框架、实践与比较

前言

在当今的软件开发中,依赖注入已经成为了一种不可或缺的设计模式。Java作为一种广泛应用的编程语言,在依赖注入领域也有着丰富的框架和实践。本文将探索Java中几种常用的依赖注入框架,包括Spring IoC、Google Guice、PicoContainer、Dagger、HK2和CDI,介绍它们的特点、用法以及适用场景,帮助读者更好地理解和选择合适的依赖注入框架。

欢迎订阅专栏:Java万花筒

文章目录

  • 探索Java依赖注入:框架、实践与比较
    • 前言
      • 1. Spring IoC
        • 1.1 概述
        • 1.2 核心功能
          • 1.2.1 Bean 定义
          • 1.2.2 依赖注入
        • 1.3 Spring Bean 的生命周期管理
          • 1.3.1 Bean 的实例化
        • 1.4 应用场景
          • 1.4.1 Web 应用
          • 1.4.2 企业级应用
        • 1.5 Spring IoC的高级特性
          • 1.5.1 切面编程
          • 1.5.2 事件驱动编程
        • 1.6 使用注解配置Bean
        • 1.7 集成测试支持
      • 2. Google Guice
        • 2.1 简介
        • 2.2 核心特性
          • 2.2.1 绑定
          • 2.2.2 依赖注入
        • 2.3 模块化
        • 2.4 配置与扩展
        • 2.5 应用示例
        • 2.6 高级特性:Guice AOP
        • 2.7 高级特性:Guice扩展
        • 2.8 Guice与其他框架集成
      • 3. PicoContainer
        • 3.1 简介
        • 3.2 核心概念
          • 3.2.1 容器
          • 3.2.2 注册
          • 3.2.3 分解器
        • 3.3 生命周期管理
        • 3.4 嵌套容器
        • 3.5 应用案例
        • 3.6 自定义组件实例化策略
        • 3.7 生命周期管理器
        • 3.8 配置文件与注解
      • 4. Dagger
        • 4.1 简介
        • 4.2 编译时生成代码
          • 4.2.1 注解处理器
          • 4.2.2 生成的依赖注入代码
        • 4.3 优势与适用场景
          • 4.3.1 性能优化
          • 4.3.2 安全性增强
        • 4.4 使用示例
        • 4.5 模块化设计
        • 4.6 生命周期管理
        • 4.7 组件化设计
        • 4.8 Android开发中的应用
      • 5. HK2
        • 5.1 概述
        • 5.2 特性与功能
          • 5.2.1 依赖注入
          • 5.2.2 生命周期管理
        • 5.3 与Java EE集成
          • 5.3.1 在GlassFish服务器上的应用
          • 5.3.2 Jersey框架中的使用
        • 5.5 事件管理
        • 5.6 定制化扩展
        • 5.7 HK2与Spring集成
        • 5.8 HK2在MicroProfile中的应用
      • 6. CDI (Contexts and Dependency Injection for Java)
        • 6.1 简介
        • 6.2 核心概念
          • 6.2.1 上下文
          • 6.2.2 依赖注入
        • 6.3 生命周期管理
          • 6.3.1 Bean的生命周期
          • 6.3.2 作用域
        • 6.4 应用示例
        • 6.5 事件管理
        • 6.6 定制化扩展
        • 6.7 CDI与其他Java EE技术集成
        • 6.8 CDI在Java SE中的应用
    • 总结

1. Spring IoC

Spring IoC(控制反转)是一个用于管理Java对象的框架,它通过将对象之间的依赖关系交给容器来管理,实现了松耦合和可测试性。以下是Spring IoC的详细介绍和示例代码:

1.1 概述

Spring IoC的核心思想是将对象的创建和依赖关系的维护交给容器管理,而不是在代码中硬编码。通过IoC容器,我们可以将各个组件解耦,降低它们之间的依赖性,从而提高代码的灵活性和可维护性。

1.2 核心功能
1.2.1 Bean 定义

在Spring中,我们可以通过XML配置文件、Java注解或者Java代码来定义Bean。下面是一个XML配置文件中定义Bean的示例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");// 获取定义的BeanHelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");helloWorld.setMessage("Hello World!");helloWorld.getMessage();}
}

beans.xml:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="helloWorld" class="com.example.HelloWorld"><property name="message" value="Hello, Spring IoC!" /></bean></beans>
1.2.2 依赖注入

Spring IoC容器会自动装配Bean之间的依赖关系,我们无需手动实例化或者管理这些依赖对象。以下是一个依赖注入的示例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class TextEditor {private SpellChecker spellChecker;@Autowiredpublic TextEditor(SpellChecker spellChecker) {this.spellChecker = spellChecker;}public void spellCheck() {spellChecker.checkSpelling();}
}
1.3 Spring Bean 的生命周期管理

Spring IoC容器管理Bean的完整生命周期,包括实例化、初始化、使用和销毁。我们可以通过实现特定接口或者使用特定注解来控制Bean的生命周期。

1.3.1 Bean 的实例化

在Spring中,Bean的实例化可以通过构造函数、工厂方法或者静态工厂方法来进行。以下是一个通过构造函数实例化Bean的示例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");helloWorld.getMessage();}
}
1.4 应用场景

Spring IoC广泛应用于各种Java应用程序中,特别是在企业级应用开发和Web应用开发中。其优点包括降低耦合性、提高代码的可测试性和可维护性。#### 1.4 应用场景

1.4.1 Web 应用

在Web应用中,Spring IoC容器通常用于管理控制器、服务层和持久层组件,实现了业务逻辑的解耦和灵活配置。例如,在Spring MVC框架中,控制器可以通过注解 @Controller@Autowired 来实现依赖注入,从而与其他组件解耦。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class HelloWorldController {@Autowiredprivate HelloWorldService helloWorldService;@RequestMapping("/hello")@ResponseBodypublic String hello() {return helloWorldService.getMessage();}
}
1.4.2 企业级应用

在企业级应用中,Spring IoC容器常用于整合各种框架和技术,实现复杂业务逻辑的管理和调度。例如,Spring与Hibernate集成可以实现数据访问层的管理,Spring与Spring Security集成可以实现安全权限控制,Spring与JMS集成可以实现消息队列的管理等等。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserDAO userDAO;public void saveUser(User user) {userDAO.save(user);}public User getUserById(int id) {return userDAO.findById(id);}
}

以上是Spring IoC的简要介绍和示例代码,Spring IoC通过依赖注入和控制反转的机制,实现了松耦合、可测试和可维护的代码编写,是Java开发中的重要组成部分。

1.5 Spring IoC的高级特性
1.5.1 切面编程

Spring IoC框架支持切面编程,可以通过AOP(面向切面编程)方式实现诸如日志记录、性能监控、事务管理等横切关注点的功能。以下是一个简单的AOP示例:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Before("execution(public * com.example.*.*(..))")public void logBefore() {System.out.println("Logging before method execution...");}
}
1.5.2 事件驱动编程

Spring IoC框架支持事件驱动编程,可以通过事件机制实现组件之间的解耦和通信。以下是一个简单的事件驱动示例:

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyEventListener implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {System.out.println("Received event: " + event.getMessage());}
}public class MyEvent extends ApplicationEvent {private String message;public MyEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}
1.6 使用注解配置Bean

除了XML配置外,Spring IoC还支持使用注解来配置Bean,使得配置更加简洁和方便。以下是一个使用注解配置Bean的示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic HelloWorld helloWorld() {return new HelloWorld();}
}
1.7 集成测试支持

Spring IoC框架提供了强大的集成测试支持,可以方便地编写和执行集成测试用例。以下是一个简单的集成测试示例:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.assertEquals;@SpringBootTest
public class IntegrationTest {@Autowiredprivate HelloWorldService helloWorldService;@Testpublic void testGetMessage() {assertEquals("Hello, Spring IoC!", helloWorldService.getMessage());}
}

以上是Spring IoC框架的高级特性和使用方法,通过了解和掌握这些内容,开发者可以更好地利用Spring IoC框架进行应用开发和测试。

2. Google Guice

Google Guice是一个轻量级的依赖注入框架,它提供了一种简洁而优雅的方式来管理Java应用程序中的对象依赖关系。以下是Guice的详细介绍和示例代码:

2.1 简介

Guice是由Google开发的一个开源项目,它允许开发者通过注解和Java配置来声明对象之间的依赖关系,从而实现依赖注入。相比于Spring IoC,Guice更加轻量级,没有XML配置文件的繁琐,更加注重Java代码的纯粹性和可读性。

2.2 核心特性
2.2.1 绑定

在Guice中,通过Module来配置对象之间的绑定关系。下面是一个简单的绑定示例:

import com.google.inject.AbstractModule;public class MyModule extends AbstractModule {@Overrideprotected void configure() {bind(Service.class).to(ServiceImpl.class);bind(Dao.class).to(DaoImpl.class);}
}
2.2.2 依赖注入

Guice通过构造函数、方法参数和字段注入等方式实现依赖注入。以下是一个构造函数注入的示例:

import com.google.inject.Inject;public class TextEditor {private SpellChecker spellChecker;@Injectpublic TextEditor(SpellChecker spellChecker) {this.spellChecker = spellChecker;}public void spellCheck() {spellChecker.checkSpelling();}
}
2.3 模块化

Guice支持模块化的配置方式,允许开发者将不同的依赖关系配置放在不同的模块中,从而使配置更加清晰和可维护。下面是一个简单的模块化配置示例:

import com.google.inject.AbstractModule;public class MyModule extends AbstractModule {@Overrideprotected void configure() {install(new ServiceModule());install(new DaoModule());}
}
2.4 配置与扩展

Guice支持通过扩展AbstractModule类来定义自定义的绑定和配置规则,使得框架更加灵活和可扩展。以下是一个自定义绑定的示例:

import com.google.inject.AbstractModule;public class MyModule extends AbstractModule {@Overrideprotected void configure() {bind(Service.class).to(AnotherServiceImpl.class);}
}
2.5 应用示例

Guice可以应用于各种Java应用程序中,包括Web应用、桌面应用和命令行应用等。以下是一个简单的Guice在Web应用中的示例:

import com.google.inject.Guice;
import com.google.inject.Injector;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class MyServlet extends HttpServlet {private MyService myService;@Overridepublic void init() throws ServletException {super.init();Injector injector = Guice.createInjector(new MyModule());myService = injector.getInstance(MyService.class);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().println(myService.sayHello());}
}

以上是Google Guice的简要介绍和示例代码,Guice通过简洁的API和灵活的配置方式,为Java开发者提供了一种优雅而轻量级的依赖注入解决方案。

2.6 高级特性:Guice AOP

除了基本的依赖注入功能之外,Google Guice还提供了AOP(面向切面编程)的支持,可以通过AspectJ等方式实现横切关注点的功能。以下是一个简单的Guice AOP示例:

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.matcher.Matchers;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;public class MyModule extends AbstractModule {@Overrideprotected void configure() {bind(Service.class).to(ServiceImpl.class);bind(Dao.class).to(DaoImpl.class);bindInterceptor(Matchers.any(), Matchers.annotatedWith(MyAnnotation.class), new MyInterceptor());}
}@Aspect
class MyInterceptor {@Before("@annotation(MyAnnotation)")public void beforeMyMethod() {System.out.println("Executing before MyMethod...");}
}public class MyService {@MyAnnotationpublic void myMethod() {System.out.println("Executing MyMethod...");}
}
2.7 高级特性:Guice扩展

Guice允许开发者通过扩展AbstractModule类来自定义绑定和配置规则,实现框架的灵活扩展。以下是一个自定义绑定的示例:

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;public class MyModule extends AbstractModule {@Overrideprotected void configure() {bind(Service.class).to(ServiceImpl.class);bind(Dao.class).to(AnotherDaoImpl.class);bindConstant().annotatedWith(Names.named("timeout")).to(1000);}
}
2.8 Guice与其他框架集成

Guice可以与其他框架集成,例如Servlet、JUnit、Jersey等,实现更强大的功能。以下是一个Guice与Servlet集成的示例:

import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;public class MyGuiceServletConfig extends GuiceServletContextListener {@Overrideprotected Injector getInjector() {return Guice.createInjector(new ServletModule() {@Overrideprotected void configureServlets() {serve("/myServlet").with(MyServlet.class);}});}
}

3. PicoContainer

PicoContainer是一个用于构建可嵌套的Java容器的轻量级框架,它提供了简单而灵活的方式来管理对象之间的依赖关系。以下是PicoContainer的详细介绍和示例代码:

3.1 简介

PicoContainer致力于提供简单的依赖注入功能,同时保持框架本身的轻量级和易用性。它通过容器的层次化和嵌套来管理对象的依赖关系,使得应用程序的组件更加模块化和可维护。

3.2 核心概念
3.2.1 容器

PicoContainer中的容器是对象的容纳者,它负责管理对象的生命周期和依赖关系。PicoContainer支持嵌套容器,使得对象的依赖关系可以以层次化的方式进行管理。

3.2.2 注册

在PicoContainer中,我们可以通过注册组件来告诉容器如何创建和管理对象。组件的注册可以通过API调用或者配置文件来进行。

3.2.3 分解器

PicoContainer使用分解器来解决对象之间的循环依赖关系,确保对象能够被正确地创建和注入。

3.3 生命周期管理

PicoContainer管理对象的完整生命周期,包括对象的创建、初始化、使用和销毁。开发者可以通过自定义的生命周期管理器来控制对象的生命周期。

3.4 嵌套容器

PicoContainer支持嵌套容器,允许开发者将不同层次的组件分别放置在不同的容器中,从而实现更加清晰和模块化的依赖管理。

3.5 应用案例

PicoContainer适用于各种Java应用程序,特别是那些需要模块化设计和灵活配置的应用。以下是一个简单的PicoContainer在插件化应用程序中的示例:

import org.picocontainer.DefaultPicoContainer;
import org.picocontainer.MutablePicoContainer;public class PluginManager {private MutablePicoContainer container;public PluginManager() {container = new DefaultPicoContainer();}public void registerPlugin(Class<?> pluginClass) {container.addComponent(pluginClass);}public <T> T getPlugin(Class<T> pluginClass) {return container.getComponent(pluginClass);}
}

以上是PicoContainer的简要介绍和示例代码,PicoContainer通过轻量级和简单的API,为Java开发者提供了一种灵活而可靠的对象依赖管理解决方案。

3.6 自定义组件实例化策略

除了使用默认的组件实例化策略外,PicoContainer还允许开发者定义自定义的组件实例化策略,以满足特定需求。以下是一个自定义组件实例化策略的示例:

import org.picocontainer.ComponentAdapter;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.defaults.DefaultPicoContainer;public class CustomComponentAdapter {public static void main(String[] args) {MutablePicoContainer container = new DefaultPicoContainer();container.addAdapter(new CustomComponentAdapterImpl(MyComponent.class));MyComponent component = container.getComponent(MyComponent.class);component.doSomething();}
}class MyComponent {public void doSomething() {System.out.println("Doing something...");}
}class CustomComponentAdapterImpl implements ComponentAdapter<MyComponent> {private final Class<? extends MyComponent> componentClass;public CustomComponentAdapterImpl(Class<? extends MyComponent> componentClass) {this.componentClass = componentClass;}@Overridepublic MyComponent getComponentInstance() {try {return componentClass.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException("Failed to instantiate component", e);}}// 其他实现方法...
}
3.7 生命周期管理器

PicoContainer允许开发者自定义生命周期管理器,以便更精细地控制对象的生命周期。以下是一个自定义生命周期管理器的示例:

import org.picocontainer.MutablePicoContainer;
import org.picocontainer.lifecycle.DefaultLifecycleState;
import org.picocontainer.lifecycle.LifecycleState;public class CustomLifecycleManager {public static void main(String[] args) {MutablePicoContainer container = new DefaultPicoContainer();container.addComponent(MyComponent.class);container.addComponent(CustomLifecycleManager.class);LifecycleState lifecycleState = new DefaultLifecycleState();container.start();lifecycleState.start();}
}class MyComponent {public void start() {System.out.println("MyComponent started.");}public void stop() {System.out.println("MyComponent stopped.");}
}
3.8 配置文件与注解

PicoContainer支持使用配置文件和注解来进行组件的注册和配置,使得开发者可以选择更适合自己项目的方式进行组件管理。以下是一个使用注解配置的示例:

import org.picocontainer.annotations.Inject;public class TextEditor {private SpellChecker spellChecker;@Injectpublic TextEditor(SpellChecker spellChecker) {this.spellChecker = spellChecker;}public void spellCheck() {spellChecker.checkSpelling();}
}

4. Dagger

Dagger是一个静态依赖注入框架,它在编译时生成依赖注入代码,从而提高了性能和安全性。以下是Dagger的详细介绍和示例代码:

4.1 简介

Dagger是由Google开发的一个轻量级的依赖注入框架,它利用Java的注解处理器技术,在编译时生成依赖注入的代码,从而避免了运行时的反射,提高了性能和安全性。

4.2 编译时生成代码
4.2.1 注解处理器

Dagger通过注解处理器在编译时扫描和处理标记了注解的类和接口,生成对应的依赖注入代码。

4.2.2 生成的依赖注入代码

生成的依赖注入代码会在编译时插入到目标类中,实现了对依赖对象的自动注入,从而避免了手动编写依赖注入的代码。

4.3 优势与适用场景
4.3.1 性能优化

由于依赖注入代码是在编译时生成的,而不是在运行时通过反射来获取,因此Dagger能够提高应用程序的性能。

4.3.2 安全性增强

Dagger通过静态分析依赖关系,能够在编译时检测到依赖关系的错误和不一致,从而提高了代码的安全性。

4.4 使用示例

Dagger适用于各种Java应用程序,特别是那些对性能和安全性要求较高的应用。以下是一个简单的Dagger在Android开发中的示例:

import dagger.Component;@Component
public interface CarComponent {Car getCar();
}public class Car {private Engine engine;@Injectpublic Car(Engine engine) {this.engine = engine;}public void start() {engine.start();System.out.println("Car started!");}
}

以上是Dagger的简要介绍和示例代码,Dagger通过静态依赖注入的方式,在编译时生成依赖注入的代码,从而提高了应用程序的性能和安全性。

4.5 模块化设计

Dagger支持模块化的设计,通过使用@Module注解和@Provides注解,开发者可以将依赖关系的配置和提供分离开来,使得代码更加清晰和可维护。以下是一个简单的模块化配置示例:

import dagger.Module;
import dagger.Provides;@Module
public class EngineModule {@ProvidesEngine provideEngine() {return new Engine();}
}
4.6 生命周期管理

Dagger提供了生命周期管理的支持,开发者可以通过@Singleton注解来标记单例对象,从而实现对单例对象的管理。以下是一个生命周期管理的示例:

import javax.inject.Singleton;@Singleton
public class Engine {public void start() {System.out.println("Engine started!");}
}
4.7 组件化设计

Dagger支持组件化的设计,通过@Component注解和@Inject注解,开发者可以将不同模块的依赖关系组合在一起,形成一个完整的组件。以下是一个组件化设计的示例:

import javax.inject.Inject;@Component(modules = {EngineModule.class})
public interface CarComponent {Car getCar();
}public class Car {private Engine engine;@Injectpublic Car(Engine engine) {this.engine = engine;}public void start() {engine.start();System.out.println("Car started!");}
}
4.8 Android开发中的应用

Dagger在Android开发中有着广泛的应用,它能够帮助开发者更好地管理Activity、Fragment、ViewModel等组件之间的依赖关系,提高了应用程序的可维护性和扩展性。

5. HK2

HK2是GlassFish服务器上的轻量级容器,它提供了依赖注入和生命周期管理等功能。以下是HK2的详细介绍和示例代码:

5.1 概述

HK2是一个开源的依赖注入框架,它是Jersey项目的一部分,被广泛用于GlassFish服务器上的应用程序开发。HK2提供了轻量级的容器和依赖注入机制,使得开发者可以更加方便地管理对象之间的依赖关系。

5.2 特性与功能
5.2.1 依赖注入

HK2支持基于构造函数、字段和方法的依赖注入,开发者可以通过注解来标记需要注入的依赖对象。

5.2.2 生命周期管理

HK2提供了灵活的生命周期管理功能,开发者可以通过自定义生命周期管理器来控制对象的创建、初始化和销毁。

5.3 与Java EE集成
5.3.1 在GlassFish服务器上的应用

HK2被广泛应用于GlassFish服务器上的Java EE应用程序开发中,它与Java EE规范紧密集成,提供了完整的依赖注入和生命周期管理功能。

5.3.2 Jersey框架中的使用

作为Jersey项目的一部分,HK2被用作Jersey框架中的依赖注入容器,为RESTful Web服务的开发提供了便利。

#### 5.4 配置方式HK2提供了多种配置方式来定义和管理对象之间的依赖关系,包括注解、XML配置文件和编程式配置等。以下是一个使用XML配置文件的示例:```java
import org.glassfish.hk2.utilities.binding.AbstractBinder;public class MyBinder extends AbstractBinder {@Overrideprotected void configure() {bind(SpellChecker.class).to(SpellChecker.class);bind(TextEditor.class).to(TextEditor.class);}
}
5.5 事件管理

HK2支持事件管理功能,开发者可以通过触发和监听事件来实现对象之间的解耦和通信。以下是一个简单的事件管理示例:

import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.messaging.Topic;public class EventPublisher {private ServiceLocator locator;public EventPublisher(ServiceLocator locator) {this.locator = locator;}public void publishEvent(String message) {Topic<String> topic = locator.getService(Topic.class);topic.publish(message);}
}
5.6 定制化扩展

HK2允许开发者通过定制化扩展来满足特定需求,例如自定义注解、自定义依赖解析器等。以下是一个自定义注解的示例:

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Fancy {
}
5.7 HK2与Spring集成

虽然HK2和Spring都是依赖注入框架,但它们可以很好地集成在一起,开发者可以同时使用它们来管理对象的依赖关系。以下是一个HK2与Spring集成的示例:

import org.glassfish.hk2.api.ServiceLocator;
import org.springframework.context.ApplicationContext;public class SpringBridge {private ServiceLocator locator;private ApplicationContext context;public SpringBridge(ServiceLocator locator, ApplicationContext context) {this.locator = locator;this.context = context;}public <T> T getService(Class<T> clazz) {if (locator.hasService(clazz)) {return locator.getService(clazz);} else {return context.getBean(clazz);}}
}
5.8 HK2在MicroProfile中的应用

MicroProfile是一个开源的微服务框架,它提供了一系列标准化的API和规范,HK2作为MicroProfile的一部分,被广泛应用于微服务应用程序的开发中。
以上是HK2的简要介绍和示例代码,HK2作为一个轻量级的依赖注入框架,广泛应用于Java EE应用程序开发中,为开发者提供了方便和灵活的依赖管理机制。

6. CDI (Contexts and Dependency Injection for Java)

CDI是Java中的上下文和依赖注入框架,为Java EE应用程序提供了依赖注入和生命周期管理功能。以下是CDI的详细介绍和示例代码:

6.1 简介

CDI是Java EE 6引入的一个规范,它为Java EE应用程序提供了上下文和依赖注入的功能。CDI允许开发者在Java EE应用程序中使用依赖注入来管理对象之间的依赖关系,从而提高了应用程序的灵活性和可维护性。

6.2 核心概念
6.2.1 上下文

CDI定义了几种上下文,包括请求上下文、会话上下文和应用程序上下文等。不同的上下文对应着不同的生命周期,开发者可以根据需要选择合适的上下文来管理对象的生命周期。

6.2.2 依赖注入

CDI通过@Inject注解实现依赖注入,开发者可以将需要注入的依赖对象声明为@Inject注解的字段、构造函数参数或者方法参数,CDI容器会自动注入这些依赖对象。

6.3 生命周期管理

CDI定义了Bean的生命周期,包括创建、初始化、使用和销毁等阶段。开发者可以通过生命周期回调方法来控制Bean的初始化和销毁过程。

6.3.1 Bean的生命周期

CDI中的Bean可以声明为ApplicationScoped、RequestScoped、SessionScoped等不同的作用域,从而控制Bean的生命周期。

6.3.2 作用域

CDI支持多种作用域,包括应用程序作用域、请求作用域、会话作用域等,开发者可以根据需要选择合适的作用域来管理Bean的生命周期。

6.4 应用示例

以下是一个简单的CDI在Java EE应用程序中的示例:

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;@Named
@RequestScoped
public class HelloBean {@Injectprivate GreetingService greetingService;public String getGreeting() {return greetingService.sayHello();}
}
6.5 事件管理

CDI提供了事件管理功能,开发者可以通过触发和监听事件来实现对象之间的解耦和通信。以下是一个简单的事件管理示例:

import javax.enterprise.event.Event;
import javax.inject.Inject;public class EventProducer {@Injectprivate Event<String> event;public void produceEvent(String message) {event.fire(message);}
}
6.6 定制化扩展

CDI允许开发者通过扩展Bean管理器和事件管理器等方式来定制化扩展框架的功能。以下是一个自定义作用域的示例:

import javax.enterprise.context.NormalScope;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@NormalScope
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomScope {
}
6.7 CDI与其他Java EE技术集成

CDI与其他Java EE技术如JPA、JSF和JAX-RS等紧密集成,开发者可以轻松地使用CDI来管理这些技术中的对象依赖关系。以下是一个CDI与JPA集成的示例:

import javax.inject.Inject;
import javax.persistence.EntityManager;public class BookService {@Injectprivate EntityManager entityManager;public void save(Book book) {entityManager.persist(book);}
}
6.8 CDI在Java SE中的应用

尽管CDI是Java EE的一部分,但它也可以在Java SE环境中使用,开发者可以通过使用Weld等CDI实现来在Java SE应用程序中实现依赖注入功能。
以上是CDI的简要介绍和示例代码,CDI作为Java EE的一部分,为Java EE应用程序提供了依赖注入和生命周期管理的功能,是Java EE应用程序开发中的重要组成部分。

总结

依赖注入是一种重要的设计模式,能够帮助我们管理对象之间的依赖关系,降低耦合度,提高代码的可测试性和可维护性。在Java领域,有许多优秀的依赖注入框架可供选择,每种框架都有着自己的特点和优势。通过本文的介绍和比较,读者可以更全面地了解Java中的依赖注入框架,选择适合自己项目需求的最佳解决方案。

这篇关于【Java万花筒】解析Java依赖注入:从Spring到CDI的全方位比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/709736

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory