shiro的DelegatingFilterProxy怎么找到ShiroFilterFactoryBean

首先看到web.xml中的配置


contextConfigLocation




        shiroFilter
        class>org.springframework.web.filter.DelegatingFilterProxyclass>
        true
        
            targetFilterLifecycle
            true
        
    
    
        shiroFilter
        /*
    

现在就引出一个问题,这里配置了ShiroFilterFactoryBean 和 DelegatingFilterProxy对象,显然这两个只是一个工厂Bean和一个委托代理对象  那么真正的shiro入口过滤器在哪儿 ?
我们进入DelegatingFilterProxy
发现其构造方法是空的
public DelegatingFilterProxy() {
}

 但是它的父类GenericFilterBean实现了InitializingBean, 那么就多了个afterPropertiesSet方法

GenericFilterBean

@Override
public void afterPropertiesSet() throws ServletException {
    initFilterBean();
}

DelegatingFilterProxy

@Override
    protected void initFilterBean() throws ServletException {
        synchronized (this.delegateMonitor) {
            if (this.delegate == null) {
                // 这个是DelegatingFilterProxy配置的名字  shiroFilter
                if (this.targetBeanName == null) {
                    this.targetBeanName = getFilterName();
                }
                WebApplicationContext wac = findWebApplicationContext();
                if (wac != null) {
            //初始化
                    this.delegate = initDelegate(wac);
                }
            }
        }
    }

protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
  //从spring上下文中根据shiroFilter(DelegatingFilterProxy配置的名字) 获取bean
Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}
return delegate;
}
 

AbstractApplicationContext

@Override
    public  T getBean(String name, Class requiredType) throws BeansException {
        assertBeanFactoryActive();
        return getBeanFactory().getBean(name, requiredType);
    }

AbstractBeanFactory

@Override
    public  T getBean(String name, Class requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }
//最终走到了doGetBean
protected
T doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // 根据web里面配置的shiroFilter的名字在spring容器中获取到了ShiroFilterFactoryBean Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { // 通过工厂获取对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }return (T) bean; }
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

  //其中有这么一句,从工厂Bean中获取Bean实例
if (object == null) {
...
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

 FactoryBeanRegistrySupport  经过枯燥的源码调用 ,来到了大门口

private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName)
      throws BeanCreationException {

   Object object;
   try {
      else {
          //调用ShiroFilterFactoryBean的getObjectct方法, ShiroFilterFactoryBean实现了FactoryBean
         object = factory.getObject();
      }
   }
   return object;
}

现在让我们来看看ShiroFilterFactoryBean

public Object getObject() throws Exception {
        if (instance == null) {
            instance = createInstance();
        }
        return instance;
    }
protected AbstractShiroFilter createInstance() throws Exception {

    SecurityManager securityManager = getSecurityManager();

  //这里有个创建过滤连管理器的方法 我们也要看看 FilterChainManager manager
= createFilterChainManager(); PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver(); chainResolver.setFilterChainManager(manager);   //这里就是最终的那个shiro的入口Filter 是 AbstractShiroFilter的子类 return new SpringShiroFilter((WebSecurityManager) securityManager, chainResolver); }

那么SpringShiroFilter就长这样,这个就是shiro的入口Filter,每次调用都会先调用它(doFilter方法在父类AbstractShiroFilter 中)

private static final class SpringShiroFilter extends AbstractShiroFilter {

        protected SpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
            super();
            if (webSecurityManager == null) {
                throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
            }
            setSecurityManager(webSecurityManager);
            if (resolver != null) {
                setFilterChainResolver(resolver);
            }
        }
    }

 

然后我们再看看createFilterChainManager

protected FilterChainManager createFilterChainManager() {
     
    //其中包含了11个默认的过滤器 DefaultFilterChainManager manager
= new DefaultFilterChainManager();
    //默认的11个过滤器
        Map defaultFilters = manager.getFilters();
        // 添加登陆、登陆成功、没有认证 的url(如果设置了的话)
        for (Filter filter : defaultFilters.values()) {
            applyGlobalPropertiesIfNecessary(filter);
        }

        /在xml文件的中配置的过滤
        Map filters = getFilters();
        if (!CollectionUtils.isEmpty(filters)) {
            for (Map.Entry entry : filters.entrySet()) {
          //拦截规则 String name
= entry.getKey();
          //过滤器 Filter filter
= entry.getValue();
          // 添加登陆、登陆成功、没有认证 的url(如果设置了的话) applyGlobalPropertiesIfNecessary(filter);
          //设置名字
if (filter instanceof Nameable) { ((Nameable) filter).setName(name); }
          //添加自定义的过滤器, 因为spring容器启动时初始化过自定义的过滤器,所以这个为初始化参数为false
manager.addFilter(name, filter, false); } } //中设置的规则与过滤器 Map chains = getFilterChainDefinitionMap(); if (!CollectionUtils.isEmpty(chains)) {
       //绑定规则与过滤器链
for (Map.Entry entry : chains.entrySet()) {
           //规则 String url
= entry.getKey();
          //过滤器链中的过滤器名称 String chainDefinition
= entry.getValue();
          //创建过滤器链 manager.createChain(url, chainDefinition); } }
return manager;
}

// 给 “每一个” 满足类型的过滤器添加添加登陆、登陆成功、没有认证 的url(如果设置了的话)
private void applyGlobalPropertiesIfNecessary(Filter filter) {
    // 需要是AccessControlFilter类型
    applyLoginUrlIfNecessary(filter);
    // 需要是 AuthenticationFilter类型
    applySuccessUrlIfNecessary(filter);
    //需要是AuthorizationFilter 类型
    applyUnauthorizedUrlIfNecessary(filter);
}
 
    
DefaultFilterChainManager
//创建过滤链
public void createChain(String chainName, String chainDefinition) {
    //  过滤器可以写成这样 { "authc", "roles[admin,user]", "perms[file:edit]" }
    String[] filterTokens = splitChainDefinition(chainDefinition);

    //这里让每一个PathConfigProcessor类型的过滤器都有该过滤器对应的所有规则  这里遍历的是过滤链字符串
    for (String token : filterTokens) {
        String[] nameConfigPair = toNameConfigPair(token);
        //添加过滤器到过滤链(一个规则对应一条过滤链)
        addToChain(chainName, nameConfigPair[0], nameConfigPair[1]);
    }
}
//添加过滤器到过滤链
public void addToChain(String chainName, String filterName, String chainSpecificFilterConfig) {
    //根据名称获取过滤器
    Filter filter = getFilter(filterName);
    //配置过滤链
    applyChainConfig(chainName, filter, chainSpecificFilterConfig);

    NamedFilterList chain = ensureChain(chainName);
    chain.add(filter);
}
//配置过滤链
protected void applyChainConfig(String chainName, Filter filter, String chainSpecificFilterConfig) {
    //如果当前过滤器是PathConfigProcessor类型 处理之
    if (filter instanceof PathConfigProcessor) {
        ((PathConfigProcessor) filter).processPathConfig(chainName, chainSpecificFilterConfig);
    }
}
 
    

PathMatchingFilter 这里将同一过滤器的所有规则设置给当前过滤器  比如 /aa=anon  /bb=anon  如果当前请求的路径是/aa 它对应的过滤器是anon 这里的appliedPaths就会有 /aa 和 /bb两个元素

      简单理解为当前拦截路径所对应的过滤器类型 对应的拦截路径(--!)

public Filter processPathConfig(String path, String config) {
    String[] values = null;
    if (config != null) {
        values = split(config);
    }
    // 添加过滤链的名称
    this.appliedPaths.put(path, values);
    return this;
}

 

小结:
  1、在启动后生成 shiroFilter -- SpringShiroFilter 入口过滤器(ShiroFilterFactoryBean类中)
  2、在会以拦截规则为key,后面的过滤器生成一条过滤链为 value的形式生成存放在map中(DefaultFilterChainManager类中)
  3、会给每个AccessControlFilter类型过滤器设置 登陆、登陆成功、没有认证 的url(ShiroFilterFactoryBean类中)

转载于:https://www.cnblogs.com/qiaozhuangshi/p/10774112.html

你可能感兴趣的:(shiro的DelegatingFilterProxy怎么找到ShiroFilterFactoryBean)