spring碎碎念

(摘自 Pro Spring MVC With Web    Flow,Deinum,Deinum,Sernells,Yates,Ladd,Vanfletern,Apress)

一、@Configuration 注解注意事项:

    1、Configuration 类可以是 abstract 的,但不可以是 final 的,因为 spring 容器动态创建其子类。

二、applicationContext加载路径:

   1、spring加载配置文件采取ant的正则表达式,classpath: 表示从项目根目录加载,classpath*:表示从当前层次,classpath**:表示从当前目录及其子目录。file:表示文件系。   

   http:表示web程序的根目录。

   2、FileSystemXmlApplicationContext 只能从本地文件系统加载,不能加载web上的配置文件。

三、用配置类配置:

    1、可以用配置类配置,例如:

@Configuration
public class ApplicationContextConfiguration {

	@Bean
	public AccountRepository accountRepository() {
		return new AccountRepository();
	}

	@Bean
	public TransactionRepository transactionRepository() {
		return new TransactionRepository();
	}
	
	@Bean
	public MoneyTransferService moneyTransferService() {
		return new MoneyTransferServiceImpl();
	}
}
加载的时候用
new AnnotationConfigApplicationContext(ApplicationContextConfiguration.class);
加载。bean的名称就是方法的名称。

不过很少看到在项目中这么干。

2、配置类使用component-scan:

只需要加上注解

org.springframework.context.annotation.ComponentScan
配置类就支持扫描。

例如:

@ComponentScan(basePackages = {
"packagea",
"packageb" })

小心:把扫描路径设置为整个classpath,或过于靠近根路径,如com.apress之类的不是一个好想法,会导致服务启动的时间过长。相信各位程序员一定有过调试时一个项目启动10多秒的时候吧,所以最好别这么设置。

四、component-scan:

1、component-scan目前支持的5种注解:

org.springframework.stereotype.Component 
org.springframework.stereotype.Service
org.springframework.stereotype.Repository
org.springframework.stereotype.Controller
org.springframework.context.annotation.Configuration

五、scope(作用域)

1、spring作用域有7种:singleton prototype thread request session globalSession application。

(1) singleton:单例,spring默认的,用于无状态的bean,就是那种方法都是给个参数,返回个值,无副作用的bean。

(2) prototype:原型,需要一个bean的时候就new 一个

(3) thread:线程,如题,在线程范围内需要bean的时候就绑定一个到当前线程,线程结束,destroy bean 。

(4) request:请求,绑定在javax.servlet.ServletRequest中,请求over,就destroy。

(5) session:会话,绑定在javax.servlet.HttpSession,session destroy,bean destroy。

(6) globalSession:全局会话,在一个portlet 范围内有效。portlet 由jsr-168定义,jsr-268更新,类似于一个子application的东东。如果没有portlet,那么就跟session是一样的。

(7) application:应用程序,绑定在javax.servlet.ServletContext,和singleton的bean很像,一个application里面只有一个bean。老实说,除了被绑定对象不同,看不出和singleton bean 有何不同。


六、Profiles(配置)

1、从spring3.1开始引入,使我们的application(程序)对于不同的environment(环境)使用不同的configuration(配置),增强了程序的可移植性与可测试性。例如可以对 测试 云环境 配置不同的profiles。指定 profile,则只加载这个 profile 中的 bean

2、使用之前,需要告诉程序激活那个configuration。通过设置spring.profiles.active来告诉系统。在web环境下,作为一个 servlet initialization parameter 或者一个 web context parameter 参数进行设置。在哪里设置?嗯,还是多加一句:在web.xml中。

3、用配置类加 profile

只需加注解

org.springframework.context.annotation.Profile

//示例
@Configuration
@Profile(value = "test")

//用法
System.setProperty("spring.profiles.active","test")
多一句,很多 Profile 一般定义在 配置类 的静态内部类上,例如:

@Configuration
public class ApplicationContextConfiguration {
    @Bean
    public Class1 bean1() {
        return new Class1();
    }

    @Configuration
    @Profile(value = "test")
    public static class TestConfig {
        @Bean
        public Class2 class2() {
            return new TestClass2();
        }
    }
    @Configuration
    @Profile(value = "local")
    public static class LocalConfig {
        @Bean
        public Class2 class2() {
            return new LocalClass2();
        }
    }
}

七、***增加内容

书中spring 版本为2.X

spring 3.x 中开始支持的注解:

1、org.springframework.transaction.annotation.EnableTransactionManagement (启用TransactionManagement)

启用特性后,支持@Transaction注解,从而自动提交与回滚。

外带提一句,spring 官方文档对其 Transaction management  这样介绍:

1、为model提供统一的 transaction api。如 java transaction api (JTA) ,hibernate,jdbc,java persistence api (JPA),java data api (JDA)。

2、支持声明式事物管理 。(declarative transaction management)

3、相较于 JTA 等,提供更简单的 API。

4、对spring 的数据访问抽象进行了出色的整合。

实际使用中也确实方便不少

2、org.springframework.context.annotation.EnableAspectJAutoProxy (启用切面自动代理)

启用特性后,支持@Aspect注解。

用法

//方式一:注解类
@Configuration
 @EnableAspectJAutoProxy
 public class AppConfig {
     @Bean
     public FooService fooService() {
         return new FooService();
     }

     @Bean
     public MyAspect myAspect() {
         return new MyAspect();
     }
 }

//方式二:注解+扫描
//方式一:注解类
@Component
public class FooService {
     // various methods
 }


//实际使用,定义一个注解

@Aspect
 public class MyAspect {
     //切片对象 * FooService+.*(..) 的意思是返回任意方法的 FooService 类中的所有任意参数的方法。
     //其他的切面定义方法参照 java 反射API
     @Before("execution(* FooService+.*(..))")
     public void advice() {
         // advise FooService methods as appropriate
     }
 }

3、org.springframework.scheduling.annotation.EnableAsync(启用异步支持)

提供类似于<task:的功能,用法:

(1)注解方式:

@Configuration
 @EnableAsync
 public class AppConfig implements AsyncConfigurer {

     @Bean
     public MyAsyncBean asyncBean() {
         return new MyAsyncBean();
     }

     @Override
     public Executor getAsyncExecutor() {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         executor.setCorePoolSize(7);
         executor.setMaxPoolSize(42);
         executor.setQueueCapacity(11);
         executor.setThreadNamePrefix("MyExecutor-");
         executor.initialize();
         return executor;
     }
 }
(2) xml方式:
<beans>
     <task:annotation-config executor="myExecutor"/>
     <task:executor id="myExecutor" pool-size="7-42" queue-capacity="11"/>
     <bean id="asyncBean" class="com.foo.MyAsyncBean"/>
 </beans>
在xml中使用,需引入命名空间
xmlns:task="http://www.springframework.org/schema/task" 
schemaLocation中引入
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
4、org.springframework.cache.annotation.EnableCaching

允许缓存,与xml配置中<catch:* 对应。

用法:

 
@Configuration
 @EnableCaching
 public class AppConfig {
     @Bean
     public MyService myService() {
         // configure and return a class having @Cacheable methods
         return new MyService();
     }

     @Bean
     public CacheManager cacheManager() {
         // configure and return an implementation of Spring's CacheManager SPI
         SimpleCacheManager cacheManager = new SimpleCacheManager();
         cacheManager.addCaches(Arrays.asList(new ConcurrentMapCache("default")));
         return cacheManager;
     }
 }
在上述用法中,必须有一个返回 CacheManager 的 cacheManager 方法。

或者

@Configuration
 @EnableCaching
 public class AppConfig implements CachingConfigurer {
     @Bean
     public MyService myService() {
         // configure and return a class having @Cacheable methods
         return new MyService();
     }

     @Bean
     @Override
     public CacheManager cacheManager() {
         // configure and return an implementation of Spring's CacheManager SPI
         SimpleCacheManager cacheManager = new SimpleCacheManager();
         cacheManager.addCaches(Arrays.asList(new ConcurrentMapCache("default")));
         return cacheManager;
     }

     @Bean
     @Override
     public KeyGenerator keyGenerator() {
         // configure and return an implementation of Spring's KeyGenerator SPI
         return new MyKeyGenerator();
     }
 }
上述方法继承了 CachingConfigurer ,必须实现 cacheManager 和 keyGenerator 两个方法。

5、org.springframework.context.annotation.EnableLoadTimeWeaving(允许时间监控)

用法

@Configuration
 @EnableLoadTimeWeaving
 public class AppConfig {
     // application-specific @Bean definitions ...
 }
或者
@Configuration
 @EnableLoadTimeWeaving
 public class AppConfig implements LoadTimeWeaverConfigurer {
     @Override
     public LoadTimeWeaver getLoadTimeWeaver() {
         MyLoadTimeWeaver ltw = new MyLoadTimeWeaver();
         ltw.addClassTransformer(myClassFileTransformer);
         // ...
         return ltw;
     }
 }
对应的XML配置:
<beans>
     <context:load-time-weaver weaverClass="com.acme.MyLoadTimeWeaver"/>
 </beans>

这个东东对于日志记录很有用,用法就是,嗯!,还是提一句:getBena("loadTimeWeaver")。呵呵。

6、org.springframework.scheduling.annotation.EnableScheduling(启用调度器)

启动后可以使用定时任务调度。

用法

@Configuration
@EnableScheduling
public class AppConfig{
}

启用后将注册启用有

@Scheduled
注解的bean

例如:

public class MyTask{
    @Scheduled(fixedRate=1000)
    public void work(){
        System.out.println("balabala")
    }
}
相应的配置类:
@Configuration
@EnableScheduling
public class AppConfig{

    @Bean
    public MyTask myTask{
        return new MyTask();
    }
}
以上配置会使new MyTask().work() 每1秒钟执行一次。


用法2:

@Configuration
@EnableScheduling
 public class AppConfig implements SchedulingConfigurer {
     @Override
     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
         taskRegistrar.setScheduler(taskExecutor());
     }

     @Bean(destroyMethod="shutdown")
     public Executor taskExecutor() {
         return Executors.newScheduledThreadPool(100);
     }
 }
需要实现 configureTasks 和 taskExecutor 两个方法。

更复杂的实现方法:

@Configuration
@EnableScheduling
public class AppConfig implements SchedulingConfigurer {
     @Override
     public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
         taskRegistrar.setScheduler(taskScheduler());
         taskRegistrar.addTriggerTask(
             new Runnable() {
                 public void run() {
                     myTask().work();
                 }
             },
             new CustomTrigger()
         );
     }

     @Bean(destroyMethod="shutdown")
     public Executor taskScheduler() {
         return Executors.newScheduledThreadPool(42);
     }

     @Bean
     public MyTask myTask() {
         return new MyTask();
     }
 }
这里又添加了一个Task

对应的xml配置

<beans>
     <task:annotation-config scheduler="taskScheduler"/>
     <task:scheduler id="taskScheduler" pool-size="42"/>
     <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
     <bean id="myTask" class="com.foo.MyTask"/>
 </beans>

7、org.springframework.web.servlet.config.annotation.EnableWebMvc(允许mvc)

激活MVC特性,注册所有有@Controller注解的类

@Configuration
@EnableWebMvc
@ComponentScan(
       basePackageClasses = { MyConfiguration.class },
       excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) }
)
public class MyConfiguration {
}
注意 上面的ComponentScan注解,里面有excludeFilters ={@Filter(type=FilterType.ANNOTATION,value=Configuration.class)},把本配置文件排除在外。

要进行进一步的定制,可以实现WebMvcConfigurer 接口或者继承WebMvcConfigurerAdapter类。

例子:

@Configuration
 @EnableWebMvc
 @ComponentScan(
        basePackageClasses = { MyConfiguration.class },
        excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) }
 )
 public class MyConfiguration extends WebMvcConfigurerAdapter {

        @Override
        public void registerFormatters(FormatterRegistry formatterRegistry) {
                formatterRegistry.addConverter(new MyConverter());
        }

        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(new MyHttpMessageConverter());
        }

        ...

 }

八、面向切面编程

几个概念:切面(Aspect)、连接点(join point)、通知(Advice)、切入点(Pointcut)

切面(Aspect):横穿几个切面的类,用org.aspectj.lang.annotation.Aspect 注解标示。

连接点(join point):程序执行过程中的一个点,在spring中,就是一个方法的执行。

通知(Advice):切入点发生的行为,常见的@Before @After @AfterThrowing @AfterReturning @Around

切入点(Pointcut):声明的所有符合条件的连接点,是一个Advice的集合。通过org.aspectj.lang.annotation.Pointcut 注解标识。

例子:

@Aspect
public class AfterThrowingExample {

  @AfterThrowing(
    pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
    throwing="ex")
  public void doRecoveryActions(DataAccessException ex) {
    // ...
  }
  
@AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
  public void doRecoveryActions() {
    // ...
  }

  
@Pointcut("execution(* com.xyz.someapp.service.*.*(..))")
  public void businessService() {}

}
注意上面的执行表达式(execution expression):

语法:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

解释下:

modifiers-pattern  访问权限匹配

ret-type-pattern 返回类型匹配

declaring-type-pattern 申明类型匹配(含包名)

name-pattern 方法名称匹配

param-pattern 参数匹配

throws-pattern 异常声明匹配

execute expression 中.. 表示所有 . 表示一个单词,*表示任意字母


九、实际web程序的入口:

1、org.springframework.web.servlet.DispatcherServlet

2、org.springframework.web.context.ContextLoaderListener





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值