@PostConstruct注解

it2022-05-08  14

目录

推荐公众号问题描述正文翻译解释官方解释--有能力看发现问题 总结

推荐公众号

有彩蛋哦!!!(或者公众号内点击网赚获取彩蛋)

问题描述

用@PostConstruct,注解做一些初始化事情时,发现会出现执行几次的情况!!!!!!, 如果执行几次,那么不是想要达到的效果所以来仔细看下@PostConstruct的说明和解释

正文

翻译解释

@PostConstruct 1.解释 PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上, 以执行任何初始化。此方法必须在将类放入服务之前调用。 支持依赖关系注入的所有类都必须支持此注释。即使类没有请求注入任何资源, 用 PostConstruct 注释的方法也必须被调用。只有一个方法可以用此注释进行注释。 应用 PostConstruct 注释的方法必须遵守以下所有标准:该方法不得有任何参数, 除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义, 在这种情况下它将带有一个 InvocationContext 对象; 该方法的返回类型必须为 void;该方法不得抛出已检查异常; 应用 PostConstruct 的方法可以是 publicprotectedpackage privateprivate;除了应用程序客户端之外,该方法不能是 static;该方法可以是 final;如果该方法抛出未检查异常,那么不得将类放入服务中, 除非是能够处理异常并可从中恢复的 EJB。 特点: 1、只有一个非静态方法能使用此注解 2、被注解的方法不得有任何参数 3、被注解的方法返回值必须为void 4、被注解方法不得抛出已检查异常 5、此方法只会被执行一次

官方解释–有能力看

/** * The PostConstruct annotation is used on a method that needs to be executed * after dependency injection is done to perform any initialization. This * method MUST be invoked before the class is put into service. This * annotation MUST be supported on all classes that support dependency * injection. The method annotated with PostConstruct MUST be invoked even * if the class does not request any resources to be injected. Only one * method can be annotated with this annotation. The method on which the * PostConstruct annotation is applied MUST fulfill all of the following * criteria: * <p> * <ul> * <li>The method MUST NOT have any parameters except in the case of * interceptors in which case it takes an InvocationContext object as * defined by the Interceptors specification.</li> * <li>The method defined on an interceptor class MUST HAVE one of the * following signatures: * <p> * void <METHOD>(InvocationContext) * <p> * Object <METHOD>(InvocationContext) throws Exception * <p> * <i>Note: A PostConstruct interceptor method must not throw application * exceptions, but it may be declared to throw checked exceptions including * the java.lang.Exception if the same interceptor method interposes on * business or timeout methods in addition to lifecycle events. If a * PostConstruct interceptor method returns a value, it is ignored by * the container.</i> * </li> * <li>The method defined on a non-interceptor class MUST HAVE the * following signature: * <p> * void <METHOD>() * </li> * <li>The method on which PostConstruct is applied MAY be public, protected, * package private or private.</li> * <li>The method MUST NOT be static except for the application client.</li> * <li>The method MAY be final.</li> * <li>If the method throws an unchecked exception the class MUST NOT be put into * service except in the case of EJBs where the EJB can handle exceptions and * even recover from them.</li></ul> * @since Common Annotations 1.0 * @see javax.annotation.PreDestroy * @see javax.annotation.Resource */ @Documented @Retention (RUNTIME) @Target(METHOD) public @interface PostConstruct { }

发现问题

这么看完好像 @PostConstruct并没有问题,想起来Service上加的 另外一个注解@RefreshScope /** * Convenience annotation to put a <code>@Bean</code> definition in * {@link org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}. * Beans annotated this way can be refreshed at runtime and any components that are using * them will get a new instance on the next method call, fully initialized and injected * with all dependencies. * * @author Dave Syer * */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Scope("refresh") @Documented public @interface RefreshScope { /** * @see Scope#proxyMode() * @return proxy mode */ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; } 大致作用在org.springframework.cloud.context.scope.refresh.RefreshScope的刷新范围内刷新,生成一个新实例,并完成依赖注入和初始化 所以 是@RefreshScope注解的原因导致@PostConstruc执行多次

总结

注意注释用于在依赖关系注入完成之后需要执行的方法上,如果结合其他注解会出现第二次执行情况

最新回复(0)