概述

  本文主要写了几个关于Spring Aware,多线程,计划任务(定时任务),条件注解,组合注解,元注解,Spring测试的小例子以及关于@Enable*注解的工作原理的理解。


Spring Aware

  简介:

    Spring的依赖注入的最大亮点就是你所有的Bean对Spring容器的存在是没有意识的。即你可以将你的容器替换成别的容器,如Google Guice,这是Bean之间的耦合度很低。

    但是在实际项目中,有时会不可避免的要用到Spring容器本身的功能资源,这是你的Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,这就是Spring Aware。

    其实Spring Aware本来就是Spring设计用来框架内部使用的,若使用了Spring Aware,你的Bean将会和Spring框架耦合。

  例子:

 package com.wisely.highlight_spring4.ch3.aware;

 import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service; import java.io.IOException; /**
* Spring Aware演示Bean
* 实现BeanNameAware、ResourceLoaderAware接口,获得Bean名称和资源加载的服务。
*/
@Service
public class AwareService implements BeanNameAware, ResourceLoaderAware {// private String beanName;
private ResourceLoader loader;
//实现ResourceLoaderAware需重写setResourceLoader方法
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {//
this.loader = resourceLoader;
}
//实现BeanNameAware需重写setBeanName方法
@Override
public void setBeanName(String name) {//
this.beanName = name;
} public void outputResult() {
System.out.println("Bean的名称为:" + beanName);
Resource resource = loader.getResource("classpath:com/wisely/highlight_spring4/ch3/aware/test.txt");
try {
System.out.println("ResourceLoader加载的文件内容为: " + IOUtils.toString(resource.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
}

Spring Aware演示Bean

 package com.wisely.highlight_spring4.ch3.aware;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* 配置类
*/
@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch3.aware")
public class AwareConfig { }

配置类

 package com.wisely.highlight_spring4.ch3.aware;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 /**
* 运行
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AwareConfig.class);
AwareService awareService = context.getBean(AwareService.class);
awareService.outputResult();
context.close();
}
}

运行

多线程

  简介:

    Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程,使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。

    而实际开发中任务一般是非阻碍的(异步的),所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解来声明其是一个异步任务。

  例子:

 package com.wisely.highlight_spring4.ch3.taskexecutor;

 import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* 任务执行类
*/
@Service
public class AsyncTaskService {
/**
* 通过@Async注解表明该方法是一个异步方法,如果注解在类级别,则表明该类所有的方法都是异步方法。
* 而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor。
* @param i
*/
@Async
public void executeAsyncTask(Integer i){
System.out.println("执行异步任务: "+i);
} @Async
public void executeAsyncTaskPlus(Integer i){
System.out.println("执行异步任务+1: "+(i+1));
} }

任务执行类

 package com.wisely.highlight_spring4.ch3.taskexecutor;

 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; /**
* 配置类
*/
@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch3.taskexecutor")
@EnableAsync //使用@EnableAsync注解开启异步任务支持
public class TaskExecutorConfig implements AsyncConfigurer {//实现AsyncConfigurer接口 /**
* 重写AsyncConfigurer接口的getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor
* 这样就可以获得一个基于线程池的TaskExecutor
* @return
*/
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//设置核心池大小
taskExecutor.setCorePoolSize(5);
//设置最大池大小
taskExecutor.setMaxPoolSize(10);
//设置队列容量
taskExecutor.setQueueCapacity(25);
//初始化
taskExecutor.initialize();
return taskExecutor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}

配置类

 package com.wisely.highlight_spring4.ch3.taskexecutor;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 /**
* 运行
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class);
for (int i = 0; i < 10; i++) {
asyncTaskService.executeAsyncTask(i);
asyncTaskService.executeAsyncTaskPlus(i);
}
context.close();
}
}

运行

计划任务(定时任务)

  简介:

    从Spring3.1开始,计划任务在Spring中的实现变得异常的简单。首先通过在配置类注解@EnableScheduling来开启对计划任务的支持,然后在要执行计划任务的方法上注解@Scheduled,声明这是一个计划任务。

    Spring通过@Scheduled支持多种类型的计划任务,包含cron、fixDelay、fixRate等。

  例子:

 package com.wisely.highlight_spring4.ch3.taskscheduler;

 import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import java.text.SimpleDateFormat;
import java.util.Date; /**
* 计划任务执行类
*/
@Service
public class ScheduledTaskService { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); /**
* 通过@Scheduled注解声明该方法是计划任务,使用fixedRate属性每隔固定时间执行。
*/
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("每隔五秒执行一次 " + dateFormat.format(new Date()));
} /**
* 1:使用cron属性可按照指定时间执行,这里是每天11点28分执行
* 2:cron是UNIX和类UNIX(Linux)系统下的定时任务
*/
@Scheduled(cron = "0 28 11 ? * *")
public void fixTimeExecution() {
System.out.println("在指定时间 " + dateFormat.format(new Date()) + "执行");
}
}

计划任务执行类

 package com.wisely.highlight_spring4.ch3.taskscheduler;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling; /**
* 配置类
*/
@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch3.taskscheduler")
@EnableScheduling //通过@EnableScheduling注解开启对计划任务的支持。
public class TaskSchedulerConfig { }

配置类

 package com.wisely.highlight_spring4.ch3.taskscheduler;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 /**
* 运行
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskSchedulerConfig.class);
}
}

运行

条件注解(@Conditional)

  简介:

    一句话来说:@Conditional注解可以根据特定条件创建特定的Bean。

  例子:

 package com.wisely.highlight_spring4.ch3.conditional;

 import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; /**
* 判断条件定义
* 判断Linux的条件
*/
public class LinuxCondition implements Condition {//实现Condition接口 /**
* 重写Condition接口的matches方法来构造判断条件
* @param context
* @param metadata
* @return
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Linux");
}
}

判断条件定义_Linux

 package com.wisely.highlight_spring4.ch3.conditional;

 import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; /**
* 判断条件定义
* 判断Windows的条件
*/
public class WindowsCondition implements Condition {//实现Condition接口 /**
* 重写Condition接口的matches方法来构造判断条件
* @param context
* @param metadata
* @return
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Windows");
}
}

判断条件定义_Windows

 package com.wisely.highlight_spring4.ch3.conditional;

 /**
* 不同系统下Bean的类
* 接口
*/
public interface ListService {
public String showListCmd();
}

不同系统下Bean的类_接口

 package com.wisely.highlight_spring4.ch3.conditional;

 /**
* 不同系统下Bean的类
* Linux下所要创建的Bean的类
*/
public class LinuxListService implements ListService{ @Override
public String showListCmd() {
return "ls";
}
}

不同系统下Bean的类_Linux

 package com.wisely.highlight_spring4.ch3.conditional;

 /**
* 不同系统下Bean的类
* Windows下所要创建的Bean的类
*/
public class WindowsListService implements ListService { @Override
public String showListCmd() {
return "dir";
}
}

不同系统下Bean的类_Windows

 package com.wisely.highlight_spring4.ch3.conditional;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; /**
* 配置类
*/
@Configuration
public class ConditionConfig { /**
* 通过@Conditional注解,符合Windows条件则实例化windowsListService
* @return
*/
@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
return new WindowsListService();
} /**
* 通过@Conditional注解,符合Linux条件则实例化linuxListService
* @return
*/
@Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService() {
return new LinuxListService();
}
}

配置类

 package com.wisely.highlight_spring4.ch3.conditional;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 /**
* 运行
*/
public class Main { public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
ListService listService = context.getBean(ListService.class);
System.out.println(context.getEnvironment().getProperty("os.name") + "系统下的列表命令为: " + listService.showListCmd());
context.close();
}
}

运行

组合注解与元注解

  简介:

    从Spring2开始,为了响应JDK1.5推出的注解功能,Spring开始大量加入注解来替代xml配置。Spring的注解主要用来配置和注入Bean,以及AOP相关配置。

    随着注解的大量使用,尤其相同的多个注解用到各个类或者方法中,会相当繁琐。这就形成了所谓的样板代码(boilerplate code),是Spring涉及原则中要消除的代码。

    所谓的元注解其实就是可以注解到别的注解上的注解,被注解的注解称之为组合注解,组合主借具备注解在上面的元注解的功能。Spring的很多注解都可以作为元注解,而且Spring本身已经有很多组合注解。如@Configuration就是一个组合@Component注解,表明这个类其实也是一个Bean。

  例子:

 package com.wisely.highlight_spring4.ch3.annotation;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import java.lang.annotation.*; /**
* 组合注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration //组合@Configuration元注解
@ComponentScan //组合@ComponentScan注解
public @interface WiselyConfiguration { String[] value() default {}; //覆盖value参数 }

组合注解

 package com.wisely.highlight_spring4.ch3.annotation;

 import org.springframework.stereotype.Service;

 /**
* 服务Bean
*/
@Service
public class DemoService { public void outputResult(){
System.out.println("从组合注解配置照样获得的bean");
}
}

服务Bean

 package com.wisely.highlight_spring4.ch3.annotation;

 /**
* 配置类
* 使用@WiselyConfiguration注解替代@Configuration和@ComponentScan注解。
*/
@WiselyConfiguration("com.wisely.highlight_spring4.ch3.annotation")
public class DemoConfig { }

配置类

 package com.wisely.highlight_spring4.ch3.annotation;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 /**
* 运行
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
DemoService demoService = context.getBean(DemoService.class);
demoService.outputResult();
context.close();
}
}

运行

测试

  简介:

    测试是开发工作中不可缺少的部分。单元测试只针对当前开发的类和方法进行测试,可以简单通过模拟依赖来实现,对运行环境没有依赖;但是仅仅进行单元测试是不够的,它只能验证当前类或方法能否正常工作,而我们想要知道系统的各个部分组合在一起是否能正常工作,这就是集成测试存在的意义。

    集成测试一般需要来自不同层的不同对象的交互,如数据库、网络连接、IoC容器等。其实我们也经常通过运行程序,然后通过自己操作来完成类似于集成测试的流程。集成测试为我们提供了一种无须部署或运行程序来完成验证系统各部分是否能正常协同工作的能力。

    Spring通过Spring TestContex Framework对集成测试提供顶级支持。它不依赖于特定的测试框架,既可以用Junit,也可以用TestNG。

  例子:

 package com.wisely.highlight_spring4.ch3.fortest;

 /**
* 测试Bean
*/
public class TestBean { private String content; public TestBean(String content) {
super();
this.content = content;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
}
}

测试Bean

 package com.wisely.highlight_spring4.ch3.fortest;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile; /**
* 测试配置类
*/
@Configuration
public class TestConfig { @Bean
@Profile("dev")
public TestBean devTestBean() {
return new TestBean("from development profile");
} @Bean
@Profile("prod")
public TestBean prodTestBean() {
return new TestBean("from production profile");
}
}

测试配置类

 package com.wisely.highlight_spring4.ch3.fortest;

 import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /**
* 测试类
*/
@RunWith(SpringJUnit4ClassRunner.class) //SpringJUnit4ClassRunner在JUnit环境下提供Spring TestContext Framework的功能。
@ContextConfiguration(classes = {TestConfig.class}) //@ContextConfiguration用来加载配置ApplicationContext,其中classes属性用来加载配置类。
@ActiveProfiles("prod") //@ActiveProfiles用来声明活动的profile。
public class DemoBeanIntegrationTests { @Autowired //可以使用普通的@Autowired注解注入Bean。
private TestBean testBean; @Test //测试代码,通过JUnit的Assert来校验结果是否和预期一致。
public void prodBeanShouldInject() {
String expected = "from production profile";
String actual = testBean.getContent();
Assert.assertEquals(expected, actual);
}
}

测试类

@Enlable*注解

  简介:

    在Spring中,大量的使用到了@Enlable*注解来开启各种功能,避免了我们自己配置大量的代码,大大降低了使用难度。下面我们来看一下它的实现原理。

    通过观察这些@Enlable*注解的源码,我们发现所有的注解都有一个@Import注解,@Import是用来导入配置类的,这也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean。

    这些导入的配置方式主要分为以下三种类型。

  第一类:

    直接导入配置类。

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.scheduling.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import; @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}

    直接导入配置类SchedulingConfiguration,这个类注解了@Configuration,且注册了一个scheduledAnnotationProcessor的Bean,源码如下。

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.scheduling.annotation; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role; @Configuration
public class SchedulingConfiguration {
public SchedulingConfiguration() {
} @Bean(
name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
)
@Role(2)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
}

  第二类:

    依据条件选择配置类。

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.scheduling.annotation; import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Import; @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AsyncConfigurationSelector.class})
public @interface EnableAsync {
Class<? extends Annotation> annotation() default Annotation.class; boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default 2147483647;
}

    AsyncConfigurationSelector通过条件来选择需要导入的配置类,AsyncConfigurationSelector的根接口为ImportSelector,这个接口需重写selectImports方法,在此方法中进行事先条件判断。

    下面的源码中,若adviceMode为PORXY,则返回ProxyAsyncConfiguration这个配置类,若activeMode为ASPECTJ,则返回AspectJAsyncConfiguration配置类。

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.scheduling.annotation; import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.AdviceModeImportSelector; public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME = "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"; public AsyncConfigurationSelector() {
} public String[] selectImports(AdviceMode adviceMode) {
switch(adviceMode) {
case PROXY:
return new String[]{ProxyAsyncConfiguration.class.getName()};
case ASPECTJ:
return new String[]{"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"};
default:
return null;
}
}
}

  第三类:

    动态注册Bean。

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.context.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
}

    AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,ImportBeanDefinitionRegistrar的作用是在运行时自动添加Bean到已有的配置类,通过重写方法:

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) 。

    其中,AnnotationMetadata参数用来获得当前配置类上的注解,BeanDefinitionRegistry参数用来注册Bean。源码如下:

 //
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.springframework.context.annotation; import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata; class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
} public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
} }
}

Spring使用_进阶的更多相关文章

  1. Spring Data JPA进阶——Specifications和Querydsl

    Spring Data JPA进阶--Specifications和Querydsl 本篇介绍一下spring Data JPA中能为数据访问程序的开发带来更多便利的特性,我们知道,Spring Da ...

  2. C++_进阶之函数模板_类模板

     C++_进阶之函数模板_类模板 第一部分 前言 c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...

  3. Spring Security框架进阶、自定义登录

      1.Spring Security框架进阶 1.1 Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安 ...

  4. 『TensorFlow』读书笔记_进阶卷积神经网络_分类cifar10_上

    完整项目见:Github 完整项目中最终使用了ResNet进行分类,而卷积版本较本篇中结构为了提升训练效果也略有改动 本节主要介绍进阶的卷积神经网络设计相关,数据读入以及增强在下一节再与介绍 网络相关 ...

  5. Spring入门(十一):Spring AOP使用进阶

    在上篇博客中,我们了解了什么是AOP以及在Spring中如何使用AOP,本篇博客继续深入讲解下AOP的高级用法. 1. 声明带参数的切点 假设我们有一个接口CompactDisc和它的实现类Blank ...

  6. JavaWeb_(session和application)用户登录注册模板_进阶版

    用户登录注册模板_基础版 传送门 用户登录注册模板进阶版 添加了获得获得当前登录用户信息及存储登录人数 用户登录后,在首页.注册页.登录页显示登录用户信息和存储登录人数信息 目录结构 <%@pa ...

  7. Spring技术_邮箱注册_激活_获取验证码

    项目结构 项目中用到的sql: create database hrSystem; use hrSystem; CREATE TABLE `emailverificationcode` ( `id` ...

  8. Spring框架_代理模式(静态代理,动态代理,cglib代理)

    共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                 ...

  9. spring设计模式_代理模式

    代理模式应该是Spring核心设计模式之一了 先说下代理模式特性: 1.有代理人和被代理人 2.对于被代理的人来说,这件事情是一定要做的,但是我又不想做,所有就找代理人来做. 3.需要获取到被代理人的 ...

随机推荐

  1. 记录一个读pcap数据包的软件:Fiddler

    Fiddler.大神推荐的.名字老忘. 用wireshark在wifi共享精灵共享出来的无线网上抓包,发现一个SSDP(简单服务发现协议)一直在尝试找连上这个网络上的设备. 连上NEXUS4后出现了I ...

  2. CentOS6.3安装 Oracle 11g R2

    1.设置系统1.1.包需求 11g很人性化了,增加了检查的机制,还有就是不象10g那样在64位下要安装很多的32位包,只需要安装一个gcc-32bit-4.3就OK了.下列表必须要安装:binutil ...

  3. groovy语言和grails框架

    Groovy 是一种动态语言,它在 JVM 上运行,并且与 Java 语言无缝集成. Groovy 可以大大减少 Java 代码的数量.在 Groovy 中,不再需要为字段编写 getter 和 se ...

  4. kafka之六:为什么Kafka那么快

    转自:  http://mp.weixin.qq.com/s?__biz=MzIxMjAzMDA1MQ==&mid=2648945468&idx=1&sn=b622788361 ...

  5. ubuntu下安装显卡驱动

    前言           以下内容是个人学习之后的感悟,转载请注明出处~ 作者的显卡是GT 730,现以NVIDIA-Linux-x86-384.69为例. 1.打开终端,先删除旧的驱动: sudo ...

  6. ubuntu删除g2o

    解决方法为:(1)删除/usr/local/include/g2o,指令为sudo rm -rf /usr/local/include/g2o:(2)删除/usr/local/lib下有关libg2o ...

  7. Eclipse如何查看接口实现类快捷键

    1.找到要打开的接口类 2.双击接口名选中 3.按Ctrl+T打开接口实现类 以List接口为例,如下所示

  8. 真正可用的Asdoc生成工具及技巧和注意事项

    经过一个上午的折腾,终于总结出一套完全能够正确运行得到asdoc api的工具.使用方便,里面写了许多注意事项,帮你顺利完成 api 的生成. ::        注意: ::        1.所以 ...

  9. CF 429B B.Working out 四个角递推

    B. Working outtime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutpu ...

  10. HDU2819【二分匹配与矩阵的秩】

    题意: 给出一个矩阵问能否实现对角线全部是1,能的话输出路径,不能的话输出-1 思路: 首先根据矩阵的性质,这一定是一个满秩矩阵,所以只根据行或列交换就一定能实现. 所以行和列构成二分图,然后跑一发匈 ...