@Autowired 与 static出现空指针
时间: 2024-03-06 22:40:17 浏览: 119
@Autowired注解用于自动装配Spring容器中的Bean对象,但是当使用@Autowired注解时,如果目标对象为null,就会出现空指针异常。
在你提供的引用中,出现空指针异常的原因是初始化顺序导致的。成员变量的初始化先于@Autowired注解,所以当@Autowired注解注入时,成员变量还没有被初始化,导致空指针异常。
要解决这个问题,你可以使用ApplicationContext来获取Bean对象,而不是直接使用@Autowired注解。在你提供的引用中,ApplicationContextHelperUtil工具类提供了从Spring上下文中获取Bean对象的方法getBean()。通过使用这个工具类,你可以避免空指针异常。
相关问题
单例模式: 将RedisTemplate封装在一个线程安全的单例类中,并在初始化时通过@Autowired注入。然后静态方法可以访问这个单例的RedisTemplate。这种方法报空指针异常
在使用单例模式封装RedisTemplate时,若在静态方法中遇到空指针异常,可能是因为以下几个原因:
1. **实例未创建或注入失败**:确保在初始化单例时,Spring的@Autowired注解能成功注入RedisTemplate。检查配置文件(如XML或注解式)中是否有正确的bean定义。
```java
@Autowired
private RedisTemplate<String, Object> redisTemplate;
```
2. **构造函数可见性**:如果是无参构造,确保没有公开的构造函数,否则可能会被外部直接创建实例,破坏单例模式。
3. **懒汉式单例初始化**:如果采用懒汉式单例模式(延迟加载),确保第一次获取时已完成初始化。使用双重检查锁定(Double-Check Locking)或并发包提供的工具类(如`ConcurrentHashMap`)。
```java
private volatile static MySingleton instance;
public static MySingleton getInstance() {
if (instance == null) {
synchronized (MySingleton.class) {
if (instance == null) {
instance = new MySingleton(redisTemplate);
}
}
}
return instance;
}
```
4. **静态域问题**:静态域的初始化顺序不是保证的,可能导致在初始化时redisTemplate还未被注入。你可以手动调用`afterPropertiesSet()`方法或在构造函数里添加必要的初始化步骤。
5. **多线程问题**:在多线程环境中,确保在初始化时加锁以防止线程安全问题。上述示例中的`synchronized`关键字就是一种简单的方式。
如果以上都排查过还是出现问题,可以添加日志跟踪具体的异常位置,以便找出导致空指针的具体原因。
1. *由容器创建和管理* *bean**,**bean* *应当为容器内单实例* * 注册 bean 方法为 register 2. *根据类型* *getBean* 3. *bean* *有基本依赖注入功能,根据**类型**进行依赖注入* 完成后应该能实现如下功能 ```java static class A { @Autowired // 自定义 private B b; public void foo() { System.out.println("A foo()"); b.bar(); } } static class B { public void bar() { System.out.println("B bar()"); } } public static void main(String[] args) { BeanFactory container = new Container(); container.register(A.class); // 注册 A container.register(B.class); // 注册 B A a = container.getBean(A.class); // 获取 A 实例 container.autowired(a); // 依赖注入 a.foo(); // 不应该出现空指针,即 B 注入成功 } ```
您可以使用以下代码来实现所需的功能:
```java
import java.util.HashMap;
import java.util.Map;
class Container implements BeanFactory {
private Map<Class<?>, Object> beanMap = new HashMap<>();
@Override
public void register(Class<?> clazz) {
try {
Object bean = clazz.getDeclaredConstructor().newInstance();
beanMap.put(clazz, bean);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public <T> T getBean(Class<T> clazz) {
return clazz.cast(beanMap.get(clazz));
}
@Override
public void autowired(Object bean) {
try {
for (var field : bean.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
field.setAccessible(true);
Class<?> fieldType = field.getType();
Object dependency = beanMap.get(fieldType);
field.set(bean, dependency);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
interface BeanFactory {
void register(Class<?> clazz);
<T> T getBean(Class<T> clazz);
void autowired(Object bean);
}
@interface Autowired {
}
static class A {
@Autowired
private B b;
public void foo() {
System.out.println("A foo()");
b.bar();
}
}
static class B {
public void bar() {
System.out.println("B bar()");
}
}
public static void main(String[] args) {
BeanFactory container = new Container();
container.register(A.class);
container.register(B.class);
A a = container.getBean(A.class);
container.autowired(a);
a.foo();
}
```
运行以上代码,输出应为:
```
A foo()
B bar()
```
阅读全文