提问者:小点点

将Spring mananged bean注入Hibernate的实体


这将不起作用(方面编织)-SlugGenerator.强击手仍然为空。请有人能看看这个,给我一个帮助吗?

  1. 我的想法是将Spring的服务编织到实体的值生成器中。我知道我可以使用实体的加载事件来注入该依赖项。
  2. 我已经仔细检查了Spring是否正确实例化了Slugify组件(我可以成功地将其注入控制器)。

Category.java(实体-域对象):

@Entity(name = "Category")
@Table(name = "category")
@Data
public class Category
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @GeneratorType(type = SlugGenerator.class, when = GenerationTime.ALWAYS)
    private String slug;

    // ...
}

SlugGenerator.java(值生成器-由Hibernate实例化):

@NoArgsConstructor
@Configurable(autowire = Autowire.BY_TYPE)
public class SlugGenerator implements ValueGenerator<String>
{
    @Autowired
    private Slugify slugger;

    @Override
    public String generateValue(Session session, Object owner) {
        Category category = (Category) owner;

        return slugger.slugify(category.getTitle());
    }
}

Slugify.java(Spring管理的服务):

@Component
public class SlugifyImpl implements Slugify {
    @Override
    public String slugify(String input)
    {
        // ...
    }
}

DispatcherConf.java(Spring会议):

public class DispatcherConf extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {ApplicationConf.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {WebConf.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/*"};
    }
}

ApplicationConf.java(Spring会议):

@Configuration
@EnableSpringConfigured
@Import({DataConf.class})
@ComponentScan(basePackages = {
        "pl.xxx.api.utils",
})
public class ApplicationConf
{
    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer() {
        return new RepositoryRestConfigurerAdapter() {
            @Override
            public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
                config.setBasePath("/api");
            }
        };
    }
}

WebConf.java(Spring会议):

@Import(RepositoryRestMvcConfiguration.class)
public class WebConf {
}

build. gradle:

// ...
compile "org.springframework:spring-aspects:$springAspects"
// ...

jvm类路径(除其他外):

aspectjrt-1.8.13.jar

IntelliJ:

Build,Execution,Deployment > Compiler > Annotation Processors > Enable Annotation Processing set to TRUE

共2个答案

匿名用户

多亏了@NándorEldFekete的评论,我明白了如何实现我的目标——将Spring管理的bean注入到由new运算符创建的实例中。

我就是这样做的:

请考虑这些注意事项:

>

  • 无法将bean注入ValueGenerator实现(SlugGenerator.java)-为什么我不知道。这是一个悬而未决的问题:)

    我已经成功地将Slugify bean注入到实体(Category.java)中。

    在Spring的配置中,我只使用了@EnableSpring配置。

    我选择使用加载时wevaing(LTW),因此我在Glassfish域的配置文件中添加了以下行:

    <jvm-options>-javaagent:/usr/local/lib/java/aspectjweaver-1.8.13.jar</jvm-options>
    

    Category.java:

    @Entity(name = "Category")
    @Table(name = "category")
    @Data
    @Configurable(autowire = Autowire.BY_TYPE)
    public class Category
    {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @GeneratorType(type = SlugGenerator.class, when = GenerationTime.ALWAYS)
        private String slug;
    
        @Autowired
        @Transient
        private Slugify slugGenerator;
        // ...
    }
    
    class SlugGenerator implements ValueGenerator<String>
    {
        @Override
        public String generateValue(Session session, Object owner) {
            Category category = (Category) owner;
            Slugify slugGenerator = category.getSlugGenerator();
    
            return slugGenerator.slugify(category.getName());
        }
    }
    

    瞧,私有属性slulgGenerator填充了Slugify接口的bean:)

  • 匿名用户

    也许这种方法会有所帮助:

    @Component
    public final class MyBeanUtils {
    
        @Autowired private ApplicationContext ctx;
    
        private static MyBeanUtils instance;
    
        @PostConstruct
        private void registerInstance() {
            instance = this;
        }
    
        public static <T> T getBean(Class<T> clazz) {
            return instance.ctx.getBean(clazz);
        }
    
        public static ApplicationContext appCtx() {
            return instance.ctx;
        }
    }
    

    然后在非托管类中使用Spring bean,例如:

    public class SlugGenerator implements ValueGenerator<String> {
    
        private Slugify slugger;
    
        public SlugGenerator() {
            slugger = MyBeansUtils.getBean(SlugifyImpl.class);
        }
    
        //...
    }