0 0

自定义securityMetadataSource不能使用依赖注入10

我在配置spring3.0.1和Security3.0.2的时候为了从数据库管理资源,自定义的securityMetadataSource,但是在类中使用依赖注入的话,加载applicationContext-security.xml的时候,会抛出使用依赖注入的那一行对象为null,是什么原因?

applicationContext-security.xml:
 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:s="http://www.springframework.org/schema/security"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans 
						   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                   		   http://www.springframework.org/schema/security 
	                       http://www.springframework.org/schema/security/spring-security-3.0.xsd"
	   default-autowire="byType" default-lazy-init="true">

	<s:http auto-config="true" access-decision-manager-ref="accessDecisionManager">
		<s:form-login login-page="/login.action" default-target-url="/"
			authentication-failure-url="/login.action?error=true" />
		<s:logout logout-success-url="/" />
		<s:remember-me key="e37f4b31-0c45-11dd-bd0b-0800200c9a66" />		
		<s:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="filterSecurityInterceptor" />		
	</s:http>  
	
	<s:authentication-manager alias="authenticationManager">
		<s:authentication-provider user-service-ref="userDetailsService">
			<s:password-encoder hash="plaintext" />
		</s:authentication-provider>  
	</s:authentication-manager>
	
	<bean id="userDetailsService" class="com.worldweboffice.service.security.UserDetailsServiceImpl" />
			
	<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">											
		<property name="authenticationManager" ref="authenticationManager"/>	
		<property name="accessDecisionManager" ref="accessDecisionManager" />
		<property name="securityMetadataSource" ref="securityMetadataSource" />
	</bean>
	
	<bean id="securityMetadataSource" class="com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource" />

	<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
		<property name="decisionVoters">		
			<list>
				<bean class="org.springframework.security.access.vote.RoleVoter">
					<property name="rolePrefix" value="A_" />
				</bean>
				<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
			</list>
		</property>
	</bean>
</beans>



MyInvocationSecurityMetadataSource:
package com.worldweboffice.modules.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

import org.apache.commons.lang.StringUtils;

import com.worldweboffice.service.security.SecurityManager;

public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    private UrlMatcher urlMatcher = new AntUrlPathMatcher();;
    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
    
	@Autowired
	private SecurityManager securityManager;
    	
    public MyInvocationSecurityMetadataSource() throws Exception {
        loadResourceDefine();
    }

      
    private void loadResourceDefine() {    	
        securityManager.getAllRole();//加载的时候,这个地方抛出securityManager对象为null
        resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
        Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
        ConfigAttribute ca = new SecurityConfig("*");
        atts.add(ca);
        resourceMap.put("/user", atts);     
    }


    // According to a URL, Find out permission configuration of this URL.
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        // guess object is a URL.
        String url = ((FilterInvocation)object).getRequestUrl();
        Iterator<String> ite = resourceMap.keySet().iterator();
        while (ite.hasNext()) {
            String resURL = ite.next();
            if (urlMatcher.pathMatchesUrl(url, resURL)) {
                return resourceMap.get(resURL);
            }
        }
        return null;
    }

    public boolean supports(Class<?> clazz) {
        return true;
    }
    
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

}

问题补充:可是我有在applicationContext.xml配置过:
<context:component-scan base-package="com.worldweboffice" />
,securityManager也用@Service注释了,自定义security的相关类中不使用依赖注入时,其他Controller依赖注入都没问题。
@Controller
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	SecurityManager securityManager;
	
	@RequestMapping(method = RequestMethod.GET)
	public String getAll(Model model) {
		User user = new User();
		user = securityManager.getUser((long)1);
		System.out.println("=============>"+user.getName());		
		return "user";		
	}

}

会打印出结果。



Anddy 写道
 SecurityManager securityManager ;


@Autowired 注解需要配合AutowiredAnnotationBeanProcessor完成自动配置

http://hi.baidu.com/sbipbje123/blog/item/179bdcde5bca4a5195ee3772.html/cmtid/9fb5b12f6cc8f8321e3089f2


问题补充:下面是抛出的问题:
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Cannot resolve reference to bean 'filterSecurityInterceptor' while setting bean property 'filterChainMap' with key [Root bean: class [java.lang.String]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with key [10]; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'filterSecurityInterceptor' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Unsatisfied dependency expressed through bean property 'objectDefinitionSource': : Error creating bean with name 'securityMetadataSource' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.NullPointerException; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityMetadataSource' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:355)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:383)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:161)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1308)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1067)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:562)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:871)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:423)
	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:272)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:196)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
	at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
	at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
	at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
	at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
	at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
	at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
	at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
	at org.apache.catalina.core.StandardService.start(StandardService.java:516)
	at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'filterSecurityInterceptor' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Unsatisfied dependency expressed through bean property 'objectDefinitionSource': : Error creating bean with name 'securityMetadataSource' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.NullPointerException; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityMetadataSource' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1150)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1040)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
	... 43 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityMetadataSource' defined in file [D:\Tomcat6\webapps\ROOT\WEB-INF\classes\applicationContext-security.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:946)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:892)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:825)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:767)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:685)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1134)
	... 51 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:72)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:939)
	... 62 more
Caused by: java.lang.NullPointerException
	at com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource.loadResourceDefine(MyInvocationSecurityMetadataSource.java:35)//这里就是调用的注入类	at com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource.<init>(MyInvocationSecurityMetadataSource.java:30)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
	... 64 more

问题补充:经验证,在加载applicationContext-security.xml的时候,使用任何依赖注入,调用的时候都会为null。

问题补充:问题不一样啊,他抛出的异常很明显:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool

我抛出的不是这个问题,是一个 java.lang.NullPointerException  
  at com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource.loadResourceDefine(MyInvocationSecurityMetadataSource.java:35)

更何况我的项目有commons-pool.jar这个包。郁闷……还是要谢谢大家的关心:)

Anddy 写道
看看这个,类似的错误。
加一个common-pool.jar
还有注意jar版本问题。
http://topic.csdn.net/u/20080424/21/894bcfd9-e9b1-492e-b275-fceb18cd5181.html


问题补充:不行吧这样,会多次加载applicationContext.xml,我在web.xml里配置过
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:/applicationContext*.xml</param-value>
	</context-param>
Anddy 写道
要是还是不行,就换这种方式初始化
 ApplicationContext ctx =     new FileSystemXmlApplicationContext("/WebContent/WEB-INF/classes/applicationContext*.xml");//注意路径
                SecurityManager securityManager= (SecurityManager)ctx.getBean("securityManager");


问题补充:是啊,没成功的原因就是:77.Caused by: java.lang.NullPointerException  
78.    at com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource.loadResourceDefine(MyInvocationSecurityMetadataSource.java:35)//这里就是调用的注入类    at com.worldweboffice.modules.security.MyInvocationSecurityMetadataSource.<init>(MyInvocationSecurityMetadataSource.java:30)  
这是不是说明在加载的过程中不能使用被注入的对象呢?这样是不是就产生了递归依赖呢?
Anddy 写道
抛出的异常:
引用
Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener  

说明加载applicationContext.xml没成功。


问题补充:如何控制顺序呢?如何让spring先加载applicationContext.xml然后再加载applicationContext-security.xml呢?
Anddy 写道
应该是的,是顺序问题。

2010年3月19日 17:02

12个答案 按时间排序 按投票排序

0 0

loadResourceDefine()方法执行后移至public Collection<ConfigAttribute> getAttributes(Object object) 
throws IllegalArgumentException中

2015年12月12日 14:56
0 0

method 为private改成public 试试。

2013年4月13日 13:26
0 0

看看这个spring是怎么加载配置文件。
http://blog.csdn.net/weoln/archive/2009/04/29/4136599.aspx

2010年3月22日 15:03
0 0

应该是的,是顺序问题。

2010年3月22日 01:29
0 0

抛出的异常:

引用
Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener  

说明加载applicationContext.xml没成功。

2010年3月20日 11:27
0 0

要是还是不行,就换这种方式初始化

 ApplicationContext ctx =     new FileSystemXmlApplicationContext("/WebContent/WEB-INF/classes/applicationContext*.xml");//注意路径
                SecurityManager securityManager= (SecurityManager)ctx.getBean("securityManager");

2010年3月19日 22:14
0 0

在MyInvocationSecurityMetadataSource类前加上@Controller 试试。

2010年3月19日 22:09
0 0

错了,可以用@Service,而且是一个很好的选择。
http://www.html.org.cn/books/springReference/ch03s12.html

2010年3月19日 22:00
0 0

引用
securityManager也用@Service注释了,

不是@Service
在类名SecurityManager前面加上 @Component注解

2010年3月19日 21:54
0 0

看看这个,类似的错误。
加一个common-pool.jar
还有注意jar版本问题。
http://topic.csdn.net/u/20080424/21/894bcfd9-e9b1-492e-b275-fceb18cd5181.html

2010年3月19日 21:46
0 0

 SecurityManager securityManager ;


@Autowired 注解需要配合AutowiredAnnotationBeanProcessor完成自动配置

http://hi.baidu.com/sbipbje123/blog/item/179bdcde5bca4a5195ee3772.html/cmtid/9fb5b12f6cc8f8321e3089f2

2010年3月19日 17:22
0 0

可能是default-lazy-init="true" 这个设置导致的吧

2010年3月19日 17:10

相关推荐

Global site tag (gtag.js) - Google Analytics