理解Spring-javaconfig

来源:互联网 发布:nymex天然气 数据 编辑:程序博客网 时间:2024/05/17 20:02

Spring初始化

Servlet3.0标准提供了ServletContainerInitializer接口和HandlesTypes注解,在Web容器启动时完成一些初始化操作,功能同ServletContextListener。

Servlet容器会扫描classpath下的所有jar中META-INF/services/javax.servlet.ServletContainerInitializer文件内容,得到一个实现类。下面是spring framework的结构:

--------------------------spring-web.jar!/META-INF/services/javax.servlet.ServletContainerInitializer文件---------------------
ServletContainerInitializer + (@HandlesTypes)
   |-(Spring): SpringServletContainerInitializer + @HandlesTypes(WebApplicationInitializer.class)
   |    .onStartup(Set<Class<?>> classes, ServletContext ctx) throws ServletException{
   |         for (WebApplicationInitializer initializer : classes){
   |             initializer.onStartup(ctx);
   |         }
   |    }

在spring中实现了一些抽象的WebApplicationInitializer:AbstractContextLoaderInitializer,AbstractDispatcherServletInitializer,AbstractAnnotationConfigDispatcherServletInitializer,AbstractSecurityWebApplicationInitializer(Spring-security)和AbstractHttpSessionApplicationInitializer(Spring-session)等。因此,要“激活”这些组件,只需新建一个空类来继承它们即可。

下面看看spring-security是怎么做到的:

首先,需要编写一个类,继承自AbstractSecurityWebApplicationInitializer,空方法即可,相当于在web.xml中定义了<filter>;

其次,编写一个空类使用注解@EnableWebSecurity即可。或者继承WebSecurityConfiguration,使用@Configuration标注它。

只需这两步,就可完成Spring-security的注入。下面在了解下@configuration

JavaConfig原理:  @Configuration (spring-context.jar)

org.springframework.stereotype
      @Component > @Controller,@Service,@Repository
org.springframework.context.annotation
      @Component > @Configuration { @Bean, @Value, @DependsOn, @ComponentScan, @Import, @ImportResource..... }

凡是被@Component(及其“子类”:@Configuration, @Controller, @Service, @Repository)标注的类,都会在启动的时候被Spring容器扫描到。

@Configuration修饰的类等价于一份spring-xml文件,它的好处就是,可以通过代码来判断分支条件(比如配置文件中的属性值),从而创建出不同的实现类。

与xml混合使用时需要注意:经测试发现,@configuration在xml之后执行,也就是说xml中的Bean找不到@configuration,反之则可以。

前置工作:

     第一种、<context:annotation-config/> + <context:component-scan base-package="..." />

     第二种:零配置
    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
     <!-- 默认:XmlWebApplicationContext -->
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
 <init-param>
            <param-name>contextConfigLocation</param-name>
     <!-- xml路径 -->
            <param-value>com.johnathanmsmith.mvc.web.config, com.johnathanmsmith.mvc.web.controller</param-value>
        </init-param>
    <servlet>

例:

public class ApplicationConfig {
private ZooKeeperTemplate template;
@Autowired
private CsrfSecurityRepository csrfRepo;
@Autowired
private XhhSessionRegistry sessionReg;

@Bean(name="zookeeperTemplate")
public ZooKeeperTemplate createZookeeperTemplate(){
if (this.repoByZookeeper()){
String zkServers = System.getProperty("springsec.registry.servers");
String rootPath = System.getProperty("springsec.registry.root");
Assert.hasText(zkServers);
Assert.hasText(rootPath);
template = new ZooKeeperTemplate(rootPath, zkServers);
return template;
}else{
return null;
}
}

@Bean
@DependsOn("zookeeperTemplate")
public CsrfTokenDao createCsrfTokenDao(){
if (this.repoByZookeeper()){
CsrfTokenDaoZkImpl csrfDao = new CsrfTokenDaoZkImpl();
csrfDao.setTemplate(template);
csrfDao.init();
csrfRepo.setCsrfTokenDao(csrfDao);
return csrfDao;
}else{
//springsession不需要
return null;
}
}

}




0 0