如何通过 XML 配置 Spring Social [英] How-to configure Spring Social via XML
问题描述
我花了几个小时尝试使用 XML 配置方法使 Twitter 集成与 Spring Social 一起使用.我在网上(和 stackoverflow)上能找到的所有例子总是使用 @Config
方法,如 样本
I spend a few hours trying to get Twitter integration to work with Spring Social using the XML configuration approach. All the examples I could find on the web (and on stackoverflow) always use the @Config
approach as shown in the samples
无论出于何种原因,获取 twitter API 实例的 bean 定义都会引发 AOP 异常:
For whatever reason the bean definition to get an instance to the twitter API throws an AOP exception:
Caused by: java.lang.IllegalStateException: Cannot create scoped proxy for bean 'scopedTarget.twitter': Target type could not be determined at the time of proxy creation.
这是我拥有的完整配置文件:
Here's the complete config file I have:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/DefaultDB" />
<!-- initialize DB required to store user auth tokens -->
<jdbc:initialize-database data-source="dataSource" ignore-failures="ALL">
<jdbc:script location="classpath:/org/springframework/social/connect/jdbc/JdbcUsersConnectionRepository.sql"/>
</jdbc:initialize-database>
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<ref bean="twitterConnectFactory" />
</list>
</property>
</bean>
<bean id="twitterConnectFactory" class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
<constructor-arg value="xyz" />
<constructor-arg value="xzy" />
</bean>
<bean id="usersConnectionRepository"
class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
<constructor-arg ref="dataSource" />
<constructor-arg ref="connectionFactoryLocator" />
<constructor-arg ref="textEncryptor" />
</bean>
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg value="#{request.userPrincipal.name}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="twitter" factory-method="findPrimaryConnection"
factory-bean="connectionRepository" scope="request" depends-on="connectionRepository">
<constructor-arg value="org.springframework.social.twitter.api.Twitter" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
factory-method="noOpText" />
<bean id="connectController" class="org.springframework.social.connect.web.ConnectController">
<constructor-arg ref="connectionFactoryLocator"/>
<constructor-arg ref="connectionRepository"/>
<property name="applicationUrl" value="https://socialscn.int.netweaver.ondemand.com/socialspringdemo" />
</bean>
<bean id="signInAdapter" class="com.sap.netweaver.cloud.demo.social.SimpleSignInAdapter" />
</beans>
令我困惑的是 connectionRepository
实例化工作得非常好(我注释掉了 twitter bean 并测试了代码!)?!?它使用相同的功能:请求范围和接口 AOP 代理和工作,但 twitter
bean 实例化失败?!?
What puzzles me is that the connectionRepository
instantiation works perfectly fine (I commented-out the twitter bean and tested the code!) ?!? It uses the same features: request scope and interface AOP proxy and works, but the twitter
bean instantiation fails ?!?
spring 社交配置代码如下所示(我看不出有什么不同,是吗?):
The spring social config code looks as follows (I can not see any differences, can you?):
@Configuration
public class SocialConfig {
@Inject
private Environment environment;
@Inject
private DataSource dataSource;
@Bean
@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public ConnectionFactoryLocator connectionFactoryLocator() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new TwitterConnectionFactory(environment.getProperty("twitter.consumerKey"),
environment.getProperty("twitter.consumerSecret")));
return registry;
}
@Bean
@Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public UsersConnectionRepository usersConnectionRepository() {
return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator(), Encryptors.noOpText());
}
@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public ConnectionRepository connectionRepository() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
}
return usersConnectionRepository().createConnectionRepository(authentication.getName());
}
@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public Twitter twitter() {
Connection<Twitter> twitter = connectionRepository().findPrimaryConnection(Twitter.class);
return twitter != null ? twitter.getApi() : new TwitterTemplate();
}
@Bean
public ConnectController connectController() {
ConnectController connectController = new ConnectController(connectionFactoryLocator(), connectionRepository());
connectController.addInterceptor(new PostToWallAfterConnectInterceptor());
connectController.addInterceptor(new TweetAfterConnectInterceptor());
return connectController;
}
@Bean
public ProviderSignInController providerSignInController(RequestCache requestCache) {
return new ProviderSignInController(connectionFactoryLocator(), usersConnectionRepository(), new SimpleSignInAdapter(requestCache));
}
}
任何帮助/指针将不胜感激!!!
Any help/pointers would be appreciated!!!
推荐答案
我有一个适用于 Spring Social Facebook 集成的配置.(我有推特配置,但我还没有测试其中的推特部分)
I have a configuration that worked for Spring Social Facebook integration. (I have twitter configuration in it, But I haven't tested the twitter part in it)
<bean class="org.springframework.social.connect.web.ProviderSignInController">
<!-- relies on by-type autowiring for the constructor-args -->
<constructor-arg ref="signInAdapter" />
</bean>
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<bean class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
<constructor-arg value="${twitter.consumerKey}" />
<constructor-arg value="${twitter.consumerSecret}" />
</bean>
<bean class="org.springframework.social.facebook.connect.FacebookConnectionFactory">
<constructor-arg value="${facebook.clientId}" />
<constructor-arg value="${facebook.clientSecret}" />
</bean>
</list>
</property>
</bean>
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg value="#{request.userPrincipal.name}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="signInAdapter" class="com.test.social.SimpleSignInAdapter"/>
<bean id="usersConnectionRepository"
class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
<constructor-arg ref="dataSource" />
<constructor-arg ref="connectionFactoryLocator" />
<constructor-arg ref="textEncryptor" />
</bean>
<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
factory-method="noOpText" />
我主要参考了文档 小到足以阅读和 教程 与 spring 安全性的集成有更多的关系.我希望这在某种程度上有所帮助.
I have primarily referred the documentation which is small enough to read and a tutorial which had more to do with integration with spring security. I hope this helps in some way.
这篇关于如何通过 XML 配置 Spring Social的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!