Spring CGLib代理 - 类变量变为空

时间:2018-05-31 09:45:23

标签: java spring-aop cglib aspect

我有一个过滤服务,其方法通过方面进行分析。作为一个例子,我会给你一段代码,我有一个问题

    @Service
    public class FilterService extends AbstractService {
        private static final Logger log = LoggerFactory.getLogger(FilterService.class);

        @Autowired
        //Proxy to profiling class
        private FilterService self;

        private final ItemsRepository itemsRepository;
        private final Map<String, EnumFilter> enumFilters;

        public FilterService(ReadWriteLock readWriteLock,
                             ItemsRepository itemsRepository,
                             CategoryRepository categoryRepository, ItemsMapper itemsMapper,
                             CharacteristicsRepository characteristicsRepository,
                             List<EnumFilter> enumFilters) {
            super(readWriteLock.readLock());
            this.itemsRepository = itemsRepository;
            this.enumFilters = enumFilters.stream().collect(Collectors.toMap(EnumFilter::getId, y -> y));
        }

        @Profileable
        public ItemsViewShared filterItems(@Nullable String categoryId,
                                           @NotNull Set<String> ids,
                                           @NotNull Lang lang,
                                           @NotNull SortType sortType,
                                           @NotNull FilterInfo filterInfo) {
            try {
                this.readLock.lock();
                final ItemsViewShared itemsViewResponse = new ItemsViewShared(); //in this line inspector show this = FilterService

                List<Filter> allFilters = self.initNonSpecificFilters(lang, filterInfo); //problem is here
      //some code...

    @Profileable
    private List<Filter> initNonSpecificFilters(@NotNull Lang lang, @NotNull FilterInfo filterInfo) {
        final List<NumericFilter> allNumericNonSpecific = NumericFilter.getAllNonSpecific(lang, filterInfo);

       //in this line enumFilters - null
        final List<EnumOptionFilter> allEnumNonSpecific = enumFilters.values().stream()
                .flatMap(x -> x.getAllOptions(lang, filterInfo).stream())
                .collect(Collectors.toList());

据我所知,默认情况下,如果类没有继承至少一个方法的接口,将使用CGlib代理,Cglib通过继承工作。
问题是这样的:当我从控制器调用 filterItems 方法时,调试器在此方法中显示 this - FilterService < / strong>即可。
此外,在该方法中,还应该引入该类的另一种方法。为了使代理工作,我需要自动自动装配。之后我通过 self.initNonSpecificFilters 调用了我的方法,在调试器中我已经看到这个 - FilterService $$ EnhancerBySpringCGLIB 以及我所有的变量我的类为null,所以我得到空指针异常。

为什么如此,如果CGLIb似乎通过继承工作?为什么在第一个方法(filterItems)这个 - 是一个没有CGlib的类,但是当你从它调用另一个方法(filterItems - &gt; initNotSpecificFilters)时,cglib已经出现了。

1 个答案:

答案 0 :(得分:1)

问题是动态代理,无论是JDK接口代理还是CGLIB类代理,都只继承

  • 公共方法(JDK,CGLIB)或
  • protected和package-scoped方法(仅限CGLIB)。

此外,代理不会继承任何实例变量值,因为这不是它们的目的,它们只包含方法并调用原始文件以及可能在方面建议或拦截器之前和之后。

现在您的情况如下:

  • 您的方法initNonSpecificFilters(..)是私有的。即如果你在self上调用它,你实际上仍会调用原始方法(因为它没有被包装),但代理的成员当然没有值。

  • 顺便说一下,这个方法是私有的这个事实也是为什么Spring AOP方面如果你有一个针对它的切入点而不能用于该方法的原因(使用AspectJ会有所不同)。

    < / LI>

Spring manual搜索自我调用这一术语,可以很好地记录该行为。

您的问题的解决方案是使该方法非私有。