代码之家  ›  专栏  ›  技术社区  ›  Peter Kozlovsky

spring cglib代理类变量变为空

  •  0
  • Peter Kozlovsky  · 技术社区  · 6 年前

    我有一个过滤服务,它的方法是通过方面分析的。作为一个例子,我将给你一段代码,我有一个问题

        @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通过继承工作。
    问题是:当我打电话给 过滤器 方法,调试器在此方法中显示 - 过滤服务 .
    此外,在这个方法中,这个类的另一个方法也应该被分析。为了让代理工作,我需要自连线。之后我通过 自初始化非特定筛选器 在调试器中我已经看到了 - FilterService$$增强Rbyspringcglib 类中的所有变量都是空的,所以我得到了空指针异常。

    为什么,如果cglib似乎是通过继承工作的呢?为什么在第一种方法中(filteritems) -是一个没有cglib的类,但是当您从它调用另一个方法(filterTimes->initNotSpecificFilters)时,cglib已经出现。

    1 回复  |  直到 6 年前
        1
  •  1
  •   kriegaex    6 年前

    问题是,不管是jdk接口代理还是cglib类代理,动态代理都只继承

    • 公共方法(jdk、cglib)或
    • 受保护和包作用域的方法(仅限cglib)。

    此外,代理不会继承任何实例变量值,因为这不是它们的目的,它们只会包装方法并调用原始值加上前后方面建议或拦截器。

    现在你的情况如下:

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

    • 顺便说一句,这个方法是私有的,这也是为什么如果你有一个针对它的切入点,spring aop方面就不会启动这个方法(对于aspectj,它会有所不同)。

    搜索 Spring manual 任期内 自我调用 ,行为被很好地记录下来。

    解决问题的方法是使方法非私有化。