对于想了解spring:当Java中有静态和非静态初始化程序时,为什么需要InitializingBean的afterPropertiesSet的读者,本文将提供新的信息,我们将详细介绍?,并且为您提
对于想了解spring:当Java中有静态和非静态初始化程序时,为什么需要InitializingBean的afterPropertiesSet的读者,本文将提供新的信息,我们将详细介绍?,并且为您提供关于Java IDEA自带的spring Initializer生成SpringBoot项目、Java Spring实现原理研究之Servlet initialization初始化过程、java – Spring:init-method,PostConstruct,afterPropertiesSet:何时使用别人?、java 含有静态代码块新建的时候报错 java.lang.ExceptionInInitializerError的有价值信息。
本文目录一览:- spring:当Java中有静态和非静态初始化程序时,为什么需要InitializingBean的afterPropertiesSet()?
- Java IDEA自带的spring Initializer生成SpringBoot项目
- Java Spring实现原理研究之Servlet initialization初始化过程
- java – Spring:init-method,PostConstruct,afterPropertiesSet:何时使用别人?
- java 含有静态代码块新建的时候报错 java.lang.ExceptionInInitializerError
spring:当Java中有静态和非静态初始化程序时,为什么需要InitializingBean的afterPropertiesSet()?
我曾经afterPropertiesSet()
在Spring
bean中初始化类属性。现在,我看到可以通过Java的内置静态和非静态初始化程序来完成此任务。afterPropertiesSet()
我不能使用初始化程序块来做什么?
答案1
小编典典鉴于以下课程
public class MyClass implements InitializingBean { static { ... } // static initializer { ... } // non-static initializer public void afterPropertiesSet() throws Exception { ... }}
的 静态 初始化代码块时,类是由类加载器加载时才执行。那时该类没有实例,您此时只能访问类级别(static
)变量,而不能访问实例变量。
的 非静态 初始化块是在构造对象,但任何属性被注入之前时。非静态初始化程序块实际上已复制到构造函数。
Java编译器将初始化程序块复制到每个构造函数中。因此,该方法可用于在多个构造函数之间共享代码块。
另请参见静态初始化块和http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
该afterPropertiesSet
或@PostConstruct
创建类的实例后,标注的方法被调用,所有的属性已设置。例如,如果您想预加载一些可以在此方法中完成的数据,因为已经设置了所有依赖项。
如果仅具有强制性依赖关系,则最好使用构造函数注入,而不要在构造函数中使用InitializingBean
或@PostConstruct
放置初始化逻辑。仅当所有依赖项都通过构造函数注入时才有效,如果您通过set方法设置了可选的依赖项,则只能使用@PostConstruct
或InitializingBean
。
Java IDEA自带的spring Initializer生成SpringBoot项目
打开IDEA,点击“文件>>新建>>项目”,选择Spring Initializr,出现以下页面:
Project SDK:选择项目的Java SDK版本
默认(通用):https://start.spring.io,项目生成结构,一般选择默认即可。
Next下一步,会看到如下页面:
组(G):com.spring.study,意为新建的这个项目属于那个分组,即:groupId
工件(A):elasticsearch,即:artifactId
类型(T):Maven Project(仓库管理方式)
语言(L):Java
打包(G):Jar
Java版本(J):8
版本(V):0.0.1-SNAPSHOT(项目版本号,可以不改)
名称(M):项目名称,可以和工件一样
描述(D):elasticsearch project for Spring Boot
包(K):com.spring.study.elasticsearch
Java Spring实现原理研究之Servlet initialization初始化过程
Created by Wang, Jerry, last modified on Jul 25, 2016
本文同步分享在 博客“汪子熙”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
java – Spring:init-method,PostConstruct,afterPropertiesSet:何时使用别人?
init-method,postconstruct注释,afterPropertiesSet,Bean后期初始化以及类构造函数.所有这些都可以用于初始化bean.
当我使用这些超过其他的时候,我感到困惑.此外,有没有一种情况我们可能需要在单个Bean中使用所有这些选项?如果是,请示例将是好的.
真的很期待得到一些很好的答案.
解决方法
您在构造函数中编写的代码将在bean的属性尚未启动时运行.所有@Autowired字段将为null.有时这是你想要的,但通常你希望代码在属性设置后运行.
除此之外,我看不出有什么区别,其他的执行顺序.我不认为有一个案例你想要在同一个类中的所有选项.
java 含有静态代码块新建的时候报错 java.lang.ExceptionInInitializerError
问题描述
最近在写一些单元测试用例,为了避免连接外界服务,所有选择 mock 了数据库 Dao 层,计划将数据库所需要的数据存在 List 中,在类加载的时候初始化 List 并且填充数据。代码如下:
1 public class UserDaoMock extends UserDao {
2 @Override
3 public List<UserInfo> selectUserInfo() {
4 return getUserInfo();
5 }
6
7 static {
8 initUserInfo();
9 }
10
11 public static UserInfo getUserInfo() {
12 return userInfos;
13 }
14
15
16 private static List<UserInfo> userInfos = new ArrayList<UserInfo>();
17 private static void initUserInfo() {
18 UserInfo userInfo1 = new UserInfo();
19 userInfo1.setId(1L);
20 userInfo1.setPin("user1");
21 userInfo1.setUserId(1L);
22 userInfo1.setDataBillingType(1);
23 userInfo1.setErp("operator1");
24 userInfo1.setCreatedTime("2019-01-01");
25 userInfo1.setModifiedTime("2019-05-01");
26 userInfo1.setYn(1);
27 userInfos.add(userInfo1);
28
29 UserInfo userInfo2 = new UserInfo();
30 userInfo2.setId(2L);
31 userInfo2.setPin("user2");
32 userInfo2.setUserId(2L);
33 userInfo2.setDataBillingType(1);
34 userInfo2.setErp("operator2");
35 userInfo2.setCreatedTime("2019-01-01");
36 userInfo2.setModifiedTime("2019-05-01");
37 userInfo2.setYn(1);
38 userInfos.add(userInfo2);
39
40 UserInfo userInfo3 = new UserInfo();
41 userInfo3.setId(3L);
42 userInfo3.setPin("user3");
43 userInfo3.setUserId(3L);
44 userInfo3.setDataBillingType(1);
45 userInfo3.setErp("operator1");
46 userInfo3.setCreatedTime("2019-01-01");
47 userInfo3.setModifiedTime("2019-05-01");
48 userInfo3.setYn(1);
49 userInfos.add(userInfo3);
50 }
51 }
结果在 new 对象的时候:
1 UserDao userDao = new UserDaoMock();
一直报错:
java.lang.ExceptionInInitializerError
at com.jd.ads.afa_index.indexes.task.TestUserServiceTask.setUp(TestUserServiceTask.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:119)
起初以为是 init 方法出错了,尝试了多种方式,才发下原来是类加载时,当执行到 static {} 语句块时开始调用 userInfos,但 userInfos 这个 list 由于是在后面而还未定义和初始化,所以导致了错误。还是因为基础知识不扎实啊!!!
问题解决
将 static 对象提到最前面,即解决了此问题,简直愚昧的我啊:
1 public class UserDaoMock extends UserDao {
2 private static List<UserInfo> userInfos = new ArrayList<UserInfo>();
3
4 @Override
5 public List<UserInfo> selectUserInfo() {
6 return getUserInfo();
7 }
8
9 static {
10 initUserInfo();
11 }
12
13 public static UserInfo getUserInfo() {
14 return userInfos;
15 }
16
17 private static void initUserInfo() {
18 UserInfo userInfo1 = new UserInfo();
19 userInfo1.setId(1L);
20 userInfo1.setPin("user1");
21 userInfo1.setUserId(1L);
22 userInfo1.setDataBillingType(1);
23 userInfo1.setErp("operator1");
24 userInfo1.setCreatedTime("2019-01-01");
25 userInfo1.setModifiedTime("2019-05-01");
26 userInfo1.setYn(1);
27 userInfos.add(userInfo1);
28
29 UserInfo userInfo2 = new UserInfo();
30 userInfo2.setId(2L);
31 userInfo2.setPin("user2");
32 userInfo2.setUserId(2L);
33 userInfo2.setDataBillingType(1);
34 userInfo2.setErp("operator2");
35 userInfo2.setCreatedTime("2019-01-01");
36 userInfo2.setModifiedTime("2019-05-01");
37 userInfo2.setYn(1);
38 userInfos.add(userInfo2);
39
40 UserInfo userInfo3 = new UserInfo();
41 userInfo3.setId(3L);
42 userInfo3.setPin("user3");
43 userInfo3.setUserId(3L);
44 userInfo3.setDataBillingType(1);
45 userInfo3.setErp("operator1");
46 userInfo3.setCreatedTime("2019-01-01");
47 userInfo3.setModifiedTime("2019-05-01");
48 userInfo3.setYn(1);
49 userInfos.add(userInfo3);
50 }
51 }
注:
类加载时不会为实例变量赋值,对象创建时不会为静态变量赋值。我们调用静态方法时,此类就开始加载,加载的时候不会为实例变量赋值,但是会按顺序给静态变量赋值。
类加载特性 :
* 在虚拟机的生命周期中一个类只被加载一次。
* 类加载的原则:延迟加载,能少加载就少加载,因为虚拟机的空间是有限的。
* 类加载的时机:
1)第一次创建对象要加载类.
2)调用静态方法时要加载类,访问静态属性时会加载类。
3)加载子类时必定会先加载父类。
4)创建对象引用不加载类.
5) 子类调用父类的静态方法时
(1) 当子类没有覆盖父类的静态方法时,只加载父类,不加载子类
(2) 当子类有覆盖父类的静态方法时,既加载父类,又加载子类
6)访问静态常量,如果编译器可以计算出常量的值,则不会加载类,例如:public static final int a =123; 否则会加载类,例如:public static final int a = math.PI。
我们今天的关于spring:当Java中有静态和非静态初始化程序时,为什么需要InitializingBean的afterPropertiesSet和?的分享已经告一段落,感谢您的关注,如果您想了解更多关于Java IDEA自带的spring Initializer生成SpringBoot项目、Java Spring实现原理研究之Servlet initialization初始化过程、java – Spring:init-method,PostConstruct,afterPropertiesSet:何时使用别人?、java 含有静态代码块新建的时候报错 java.lang.ExceptionInInitializerError的相关信息,请在本站查询。
本文标签: