Java Resource案例怎么依赖注入

wen java案例 24

本文目录导读:

Java Resource案例怎么依赖注入

  1. @Resource基本案例
  2. @Resource@Autowired的区别
  3. 纯Java EE/Jakarta EE环境(非Spring)
  4. 使用@Resource处理多个同类型Bean
  5. 完整可运行示例(Spring Boot)

在Java中,依赖注入(DI)的实现方式有多种,包括手动注入、使用框架(如Spring、Guice)或Java EE的CDI。

这里根据你的疑问“Java Resource案例怎么依赖注入”,我理解你可能是遇到了@Resource注解(javax.annotation.Resource)的用法问题。@Resource是Java EE/Jakarta EE提供的一个标准注解,用于实现依赖注入。

下面给出几个典型的案例,涵盖不同的使用场景。


@Resource基本案例

假设我们有一个UserService,它需要依赖一个UserRepository

创建依赖类

import org.springframework.stereotype.Repository;
// 或者 @Component, @Service 等
@Repository
public class UserRepository {
    public String findUserById(int id) {
        return "User_" + id;
    }
}

使用 @Resource 注入(在Spring中)

import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    // 方式1:字段注入(byName 默认匹配字段名 userRepository)
    @Resource
    private UserRepository userRepository;
    // 方式2:通过name属性指定要注入的bean名称
    // @Resource(name = "userRepository")
    // private UserRepository repo;
    public void printUser(int id) {
        String user = userRepository.findUserById(id);
        System.out.println("User: " + user);
    }
}

手动触发(测试或简单容器环境)

如果在非Spring容器中,你需要手动创建对象并注入:

public class ManualDIExample {
    public static void main(String[] args) {
        UserRepository repository = new UserRepository();
        UserService service = new UserService();
        // 手动注入(相当于setter注入)
        service.setUserRepository(repository); // 需要一个setter方法
        service.printUser(1);
    }
}

@Resource@Autowired的区别

特性 @Resource (javax.annotation) @Autowired (Spring)
来源 Java EE / Jakarta EE Spring 专属
匹配策略 先按名称(byName),找不到再按类型(byType) 先按类型(byType)
指定名称 @Resource(name="xxx") @Qualifier("xxx")
作用范围 字段、setter方法 字段、构造器、setter

使用建议:如果在Spring项目里,推荐统一使用@Autowired+@Qualifier,如果希望与Java EE标准兼容(例如迁移到其他框架),可以使用@Resource


纯Java EE/Jakarta EE环境(非Spring)

在Jakarta EE容器(如TomEE、WildFly、GlassFish)中,@Resource常用于注入容器管理的资源,例如DataSourceEJBJMS等。

案例:注入数据库数据源

import javax.annotation.Resource;
import javax.sql.DataSource;
import jakarta.ejb.Stateless;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@Stateless
public class UserDao {
    @Resource(lookup = "java:jboss/datasources/ExampleDS")  // 根据容器配置
    private DataSource dataSource;
    public String getUserName(int id) {
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement("SELECT name FROM users WHERE id = ?")) {
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                return rs.getString("name");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

使用@Resource处理多个同类型Bean

当同一个接口有多个实现类时,@Resource可以通过name属性进行精确匹配。

// 接口
public interface PaymentService {
    void pay(double amount);
}
// 实现1
@Repository("alipayService")
public class AlipayService implements PaymentService {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付:" + amount);
    }
}
// 实现2
@Repository("wechatPayService")
public class WechatPayService implements PaymentService {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付:" + amount);
    }
}
// 使用 @Resource 指定名称
@Service
public class OrderService {
    @Resource(name = "alipayService")  // 明确指定注入哪一个
    private PaymentService paymentService;
    public void checkout(double amount) {
        paymentService.pay(amount);
    }
}

完整可运行示例(Spring Boot)

项目结构

src/main/java/com/example/demo
 ├── DemoApplication.java
 ├── repository/UserRepository.java
 └── service/UserService.java

启动类

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        var context = SpringApplication.run(DemoApplication.class, args);
        UserService service = context.getBean(UserService.class);
        service.printUser(1);
    }
}

UserRepository

@Repository
public class UserRepository {
    public String findUserById(int id) {
        return "User_" + id;
    }
}

UserService(使用@Resource)

import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Resource
    private UserRepository userRepository;
    // 如果字段名与bean名不一致,可以指定name
    // @Resource(name = "userRepository")
    // private UserRepository repo;
    public void printUser(int id) {
        String user = userRepository.findUserById(id);
        System.out.println("User: " + user);
    }
}

输出User: User_1


场景 推荐做法
Spring项目,简单注入 @Autowired
需要按名称匹配多个同类型Bean @Resource(name="xxx")@Autowired+@Qualifier
希望代码与Spring解耦(可移植到其他容器) @Resource
Java EE / Jakarta EE 环境(注入数据源、EJB等) @Resource(lookup="...")

如果你是在Spring项目中遇到@Resource不生效,请确认:

  1. 类上标注了@Component/@Service/@Repository等Spring注解。
  2. 项目引入了javax.annotation-apijakarta.annotation-api依赖。
  3. 没有人为禁用@Resource解析(Spring默认支持)。

希望这些案例能帮你解决依赖注入的疑问,如果有更具体的报错或场景,请补充说明。

抱歉,评论功能暂时关闭!