1. Spring基础配置

Spring框架本身有四大原则:

1) 使用POJO进行轻量级和最小侵入式开发

2) 通过依赖注入和基于接口编程实现松耦合

3) 通过AOP和默认习惯进行声明式编程

4) 使用AOP和模板(template)减少模式化代码

所谓依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。依赖注入主要目的是为了解耦。

Spring Ioc容器(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注入到你需要的Bean中。

声明Bean的注解:

a. @Component组件

b. @Service在业务逻辑层(Service层)使用

c. @Repository在数据访问层(dao层)使用

e. @Controller在展现层使用

注入Bean的注解,一般情况下是通用的:

a. @Autowired:Spring提供的注解

b. @Resourse: JSR-250提供的注解

c. @Inject: JSR-330提供的注解

示例:

1) 构件maven项目,其pom.xml配置文件如下:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.ws</groupId>
<artifactId>study1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>study1</name>
<url>http://maven.apache.org</url> <properties>
<java.version>1.7</java.version>
<spring-framework.version>4.1.5.RELEASE</spring-framework.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
</dependencies>
</project>

2) 编写功能类Bean

 package com.ws.study.one;

 import org.springframework.stereotype.Service;

 // @Service注解声明当前FunctionService类是Spring管理的一个Bean
@Service
public class FunctionService {
public String sayHello(String word){
return "Hello " + word + " !";
}
}

3) 使用编写好的功能类Bean

 package com.ws.study.one;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; // @Service注解声明当前类是Spring管理的一个Bean
@Service
public class UseFunctionService { // @Autowired实体将FunctionService的实体Bean注入到UseFunctionService中,
// 进而使UseFunctionService具备FunctionService的功能
@Autowired
FunctionService functionService; public String sayHello(String word){
return functionService.sayHello(word);
}
}

4) 配置类

 package com.ws.study.one;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; // @Component声明当前类是一个配置类
@Component
// 使用@ComponentScan,自动扫描包下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean
@ComponentScan("com.ws.study.one")
public class DiConfig { }

5) 运行类

 package com.ws.study.one;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 public class Main {
public static void main(String[] args) {
// 使用AnnotationConfigApplicationContext作为Spring容器,接受输入一个配置类作为参数
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DiConfig.class); // 获取声明配置的UseFunctionService的Bean
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class); System.out.println(useFunctionService.sayHello("di")); context.close();
}
}

6) 运行结果

 五月 29, 2018 11:07:20 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:07:20 CST 2018]; root of context hierarchy
Hello di !
五月 29, 2018 11:07:20 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:07:20 CST 2018]; root of context hierarchy

2. Java配置

java配置可以完全替代xml配置,也是Spring Boot推荐的配置方式。java配置是通过@Configuration和@Bean来实现的。

a. @Configuration声明当前类是一个配置类,相当于一个Spring配置的xml文件

b. @Bean注解在方法上,声明当前方法的返回值是一个Bean

何时使用java配置或注解配置?原则:全局配置使用java配置(如数据库配置、MVC相关配置),业务Bean的配置使用注解配置(@Service、@Component、@Repository、@Controller)

示例:

1) 编写功能类

 package com.ws.study.javaconfig;

 // 此处没有@Service声明的Bean
public class FunctionService {
public String sayHello(String word){
return "Hello " + word + " !";
}
}

2) 使用功能类

 package com.ws.study.javaconfig;

 //此处没有@Service声明的Bean
public class UseFunctionService {
// 此处没有@Autowired声明的Bean
FunctionService functionService; public void setFunctionService(FunctionService functionService) {
this.functionService = functionService;
} public String sayHello(String word){
return functionService.sayHello(word);
}
}

3) 配置类

 package com.ws.study.javaconfig;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; // 使用@Configuration注解声明当前类是一个配置类。意味着这个类中可能存在0个或多个@Bean注解
// 此处没有使用包扫描,是因为所有的Bean都在此类中定义了
@Configuration
public class JavaConfig { // 使用@Bean注解声明当前方法FunctionService的返回值是一个Bean,Bean的名称是方法名
@Bean
public FunctionService functionService(){
return new FunctionService();
} @Bean
public UseFunctionService useFunctionService(){
UseFunctionService useFunctionService = new UseFunctionService();
// 注入FunctionService的Bean时候直接调用functionService()
useFunctionService.setFunctionService(functionService());
return useFunctionService;
} // // 另外一种注解方式,直接将FunctionService作为参数给useFunctionService()
// // 在Spring容器中,只要容器中存在某个Bean,就可以在另外一个Bean的声明方法的参数中写入
// @Bean
// public UseFunctionService useFunctionService(FunctionService functionService){
// UseFunctionService useFunctionService = new UseFunctionService();
// useFunctionService.setFunctionService(functionService);
// return useFunctionService;
// }
}

4) 运行类

 package com.ws.study.javaconfig;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class); UseFunctionService useFunctionService = context.getBean(UseFunctionService.class); System.out.println(useFunctionService.sayHello("java config")); context.close();
}
}

5) 运行结果

 五月 29, 2018 11:36:47 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:36:47 CST 2018]; root of context hierarchy
Hello java config !
五月 29, 2018 11:36:47 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1fc0f2f: startup date [Tue May 29 23:36:47 CST 2018]; root of context hierarchy

3. AOP

AOP为面向切面编程,切面编程是指在程序运行期间将某段代码,动态的切入到某个类的指定方法的指定位置。AOP存在的目的是为了解耦。AOP可以让一组类共享相同的行为。Spring支持AspectJ的注解式切面编程。

a. 使用@AspectJ声明是一个切面

b. 使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。为了使拦截规则(切点)复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。

c. 其中符合条件的每一个被拦截处为连接点(JoinPoint)

Spring本身在事务处理(@Transcational)和数据缓存(@Cacheable)上面都使用注解式拦截。

示例:

1) 添加spring aop支持及AspectJ依赖

 		<!-- spring aop支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- aspectj支持 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>

2) 编写拦截规则的注解

 package com.ws.study.aop;

 import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; // 注解本身没有功能
// 注解和XML都是元数据
// 注解的功能来自用这个注解的地方
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
}

3) 编写使用注解的被拦截类

 package com.ws.study.aop;

 import org.springframework.stereotype.Service;

 @Service
public class DemoAnnotationService {
@Action(name = "注解式拦截的add操作")
public void add(){}
}

4) 编写使用方法规则被拦截类

 package com.ws.study.aop;

 import org.springframework.stereotype.Service;

 @Service
public class DemoMethodService {
public void add(){}
}

5) 编写切面

 package com.ws.study.aop;

 import java.lang.reflect.Method;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; // @Aspect注解声明一个切面
@Aspect
// @Component让此切面成为Spring容器管理的Bean
@Component
public class LogAspect { // @Pointcut注解声明切点
@Pointcut("@annotation(com.ws.study.aop.Action)")
public void annotationPointCut(){}; // 通过@After注解声明一个建言,并使用@PointCut定义的切点
@After("annotationPointCut()")
public void after(JoinPoint joinpoint){
MethodSignature signature = (MethodSignature) joinpoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
// 通过反射可获取注解上的属性,然后做日志记录相关的操作
System.out.println("注解式拦截:"+action.name());
} // 通过@Before注解声明一个建言,此建言直接使用拦截规则作为参数
@Before("execution(* com.ws.study.aop.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截: "+method.getName());
}
}

6) 配置类

 package com.ws.study.aop;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@ComponentScan("com.ws.study.aop")
// 使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持
@EnableAspectJAutoProxy
public class AopConfig { }

7) 运行类

 package com.ws.study.aop;

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 public class Main {

 	public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class); DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
demoAnnotationService.add(); DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
demoMethodService.add(); context.close();
} }

8) 运行结果

 五月 30, 2018 10:06:14 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1531931: startup date [Wed May 30 22:06:14 CST 2018]; root of context hierarchy
注解式拦截:注解式拦截的add操作
方法规则式拦截: add
五月 30, 2018 10:12:09 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1531931: startup date [Wed May 30 22:06:14 CST 2018]; root of context hierarchy

Spring Boot实战(1) Spring基础的更多相关文章

  1. Spring Boot实战(3) Spring高级话题

    1. Spring Aware Spring的依赖注入的最大亮点就是你所有的Bean对Spring容器的存在是没有意识的.即你可以将你的容器替换成别的容器. 实际项目中,不可避免地会用到Spring容 ...

  2. Spring Boot实战(2) Spring常用配置

    1. Bean的Scope scope描述Spring容器如何新建Bean的实例.通过注解@Scope实现,取值有: a. Singleton:一个Spring容器中只有一个Bean的实例.此为Spr ...

  3. Spring Boot实战

    Spring在java EE开发中是实际意义上的标准,但我们在开发Spring的时候可能会遇到以下令人头疼的问题: 1.大量配置文件的定义.2.与第三方软件整合的技术问题. Spring每个版本的退出 ...

  4. 《spring boot 实战》读书笔记

    前言:虽然已经用spring boot开发过一套系统,但是之前都是拿来主义,没有系统的,全面的了解过这套框架.现在通过学习<spring boot实战>这本书,希望温故知新.顺便实现自己的 ...

  5. Spring Boot实战系列-----------邮件发送

    快速导航 添加Maven依赖 配置文件增加邮箱相关配置 Service.Test项目代码构建 五种邮件发送类型讲解 文本邮件 html邮件 附件邮件 html内嵌图片邮件 模板邮件 问题汇总 添加ma ...

  6. 《Spring Boot实战》笔记(目录)

    目录 目 录第一部分 点睛Spring 4.x第1 章 Spring 基础 .............................................................. ...

  7. spring boot 实战教程

    二八法则 - get more with less Java.spring经过多年的发展,各种技术纷繁芜杂,初学者往往不知道该从何下手.其实开发技术的世界也符合二八法则,80%的场景中只有20%的技术 ...

  8. 《Spring Boot 实战纪实》之需求管理

    目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...

  9. 《Spring Boot 实战纪实》之前言

    目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...

随机推荐

  1. MVC下为什么要使用Areas

    想研究一下这个Areas,在博客园知识库找到这篇文章,先全部搬过来吧,原文地址:http://kb.cnblogs.com/page/144561/ 为什么需要分离? 我们知道MVC项目各部分职责比较 ...

  2. js 值传递,引用传递

    参考:http://www.cnblogs.com/lcngu/p/5876273.html JS的基本类型,是按值传递的. 对象类型按共享传递的(call by sharing,也叫按对象传递.按对 ...

  3. [转]Marshaling a SAFEARRAY of Managed Structures by P/Invoke Part 3.

    1. Introduction. 1.1 In part 1 of this series of articles, I demonstrated how to transfer managed ar ...

  4. Failed to export using the options you specified. Please check your options and try again

    参考这篇<从ASP.NET传递参数给水晶报表> http://www.cnblogs.com/insus/p/3281114.html  是可以传递参了.但是点击报表的菜单条上的打印图标没 ...

  5. Binder学习笔记(四)—— ServiceManager如何响应checkService请求

    这要从frameworks/native/cmds/servicemanager/service_manager.c:347的main函数说起,该文件编译后生成servicemanager. int ...

  6. IOS中录音后再播放声音太小问题解决

    1.AVAudioSessionCategory说明 1.1 AVAudioSessionCategoryAmbient 或 kAudioSessionCategory_AmbientSound 用于 ...

  7. [hdu 2089] 不要62 数位dp|dfs 入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意:求[n, m]区间内不含4和62的数字个数. 这题有两种思路,直接数位dp和dfs 数位d ...

  8. JDK源码 Integer.bitCount(i)

    1.问题:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 2.解决方法很多,JDK提供了一种,如下图 /** * Returns the number of one-bits in ...

  9. join与os.path.join

    Python中有join和os.path.join()两个函数,具体作用如下: join:连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串os.path.joi ...

  10. springdataRedis连接redis集群

    配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...