最近又重新学习了下spring和spring mvc,有一些收获,为了记下这些收获,整理成学习笔记,方便日后在进行复习使用。
spirng使用简单的POJO(plain old java object ,及无任何限制的普调java对象)来进行企业级开发。每一个被spring管理的java对象都称之为bean;spring提供了一个ioc容器来初始化对象,解决对象之间的依赖管理和对象的使用。
apache maven是一个软件项目管理工具,基于项目对象模型(project object model POM)的概念,maven可以用来管理项目的依赖,编译,文档信息。
Maven的安装:
1,下载Maven
Maven的下载地址:https://maven.apache.org/download.cgi
根据自己的操作系统下载对应的maven版本,并解压到任意目录。
我的是win8.1的系统,下载win版本,解压到我的d盘:D:\apache-maven-3.3.9
2,配置Maven
把maven加压后,在系统属性-》高级-》环境变量中分别配置M2_HOME 和 Path,如下图:
3,Maven测试安装
配置之后,我们需要进行测试,看是否配置正确,在控制台输入mvn - v,出现如下信息表示安装成功:
4,maven的pom.xml
maven是基于项目对象模型的概念运作的,所以maven的项目都有一个pom.xml用来管理项目的依赖以及项目的编译等功能。
在我们的项目中我们主要关注下面的元素。
1)dependencies元素
<dependencies></dependenies>,此元素包含了多个项目依赖需要使用的<dependency></dependency>
2)dependency元素
<dependency></dependency> 内部通过groupId,artifactId,以及version确定唯一的依赖,
groupId:组织的唯一标识
artifactId:项目的唯一标识
version:项目的版本
<!--对json和xml格式的支持-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.5.3</version>
</dependency>
3)变量定义
变量的定义<properties></properties>可定义变量在dependency中引用,代码如下。
<!--常量配置-->
<properties>
<!--generic properties-->
<java.version>1.7</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--web-->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>3.1.0</servlet.version>
<!--spring-->
<spring-framework.version>4.1.5.RELEASE</spring-framework.version>
<!--Logging-->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
</properties>
4)编译插件
maven提供了编译插件,可在编译插件中涉及java的编译级别,代码如下。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<source>1.7</source>
</configuration>
</plugin>
</plugins>
</build>
5,Maven运作方式
Maven会自动根据dependency中的依赖配置,直接通过互联网在maven中心库下载相关依赖包到.m2目录下,.m2目录下是你本地Maven库。
如果不知道你所依赖jar的dependency怎么写的话,推荐到http://mvnrepository.com网站检索。
若Maven中心库中没有你需要的jar包(如oracle),你需要通过下面的maven命令打到本地maven库后应用即可,如安装Oracle驱动到本地库:
mvn install:install-file -DgroupId=com.oracle "-DartifactId=ojdbc14" "-Dversion=10.2.0.2.0" "-Dpackaging=jar" "-Dfile=D:\ojdbc14.jar"
6,基于IntelliJ IDEA 搭建spring
首先要下载IntelliJ IDEA ,IntelliJ IDEA 分为社区版和商业版,社区版免费但是功能不全,商业版收费需要注册码进行破解,开发web用IntelliJ IDEA ,只能使用商业版本ideaIU版本,
IntelliJ IDEA下载地址:https://www.jetbrains.com/idea/download/
下载之后就行安装破解,破解的方法可以网上找。
打开IntelliJ IDEA:
1)新建Maven项目。单击File-New-Project-Maven
给IntelliJ IDEA添加JDK,如下图:
2)输入Maven项目坐标
3)选择存储路径
4)修改pom.xml,IDEA会开启自动导入Maven依赖包功能
<?xml version="1.0" encoding="UTF-8"?>
<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.jack</groupId>
<artifactId>srping4test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.7</java.version>
<spring-framework.version>4.1.6.RELEASE</spring-framework.version>
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!--添加spring的支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!--添加spring aop的支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!--aspectj的支持-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
<!--文件操作包-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<!--spring test支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}}</source>
<source>${java.version}}</source>
</configuration>
</plugin>
</plugins>
</build>
</project>
到这里spring项目的配置就搭建完成了。
上面给出了一些组件的spring包了,如果我们只是搭建一个很简单spring,之要使用下面的pom.xm就行了如下:
<?xml version="1.0" encoding="UTF-8"?>
<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.jack</groupId>
<artifactId>springstudy1</artifactId>
<version>1.0-SNAPSHOT</version>
<!--定义属性-->
<properties>
<java.version>1.8</java.version>
</properties>
<!--添加依赖-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
</dependencies>
<!--添加插件-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
7,spring基础配置
spring框架本身的四大原则:
1)使用POJO进行轻量级和最小侵入式开发。
2)通过依赖注入和基于接口编程实现松耦合
3)通过AOP和默认习惯进行声明式编程
4)使用AOP和模板减少模式化代码
spring的所有功能的设计和实现都是基于此四大原则。
8,spring 的依赖注入
控制反转ioc和依赖注入DI,所谓依赖注入指的是容器负责创建对象和维护对象之间的关系,而不是通过对象本身负责自己的创建和解决自己的依赖。
spring的IOC容器负责传教Bean,并通过容器将功能类Bean注入到你需要的Bean中。spring提供使用xml,注解,java配置,groovy配置实现bean的创建和注入。
无论是xml配置,注解配置还是java配置,都被称为配置元数据,所谓元数据即描述数据的数据。元数据本事不具备任何执行的能力,只能通过外界代码来对这些元数据解析后进行一些有意义操作。spring容器解析这些配置元数据进行Bean初始化,配置和管理依赖。
声明Bean的注解:
@Component组件,没有明确的角色
@Service在业务逻辑层(service)使用
@Repository 在数据访问层(dao层)使用
@Controller 在展现层(mvc-spring mvc)使用
注入bean的注解,一般情况下通用:
@Autowired:Spring 提供的注解
@Inject:JSR-330 提供的注解
@Resource : JSR-250 提供的注解
@Autowired,@Inject,@Resource可注解在set方法上或者属性上,一般习惯注解在属性上,优点是代码少,层次更清晰。
一:下面演示基于注解的Bean的初始化和依赖注入,spring容器类选用AnnotationConfigApplication.
1,编写功能类的bean代码如下:
package jack.ch1.bean;
import org.springframework.stereotype.Service;
/**
* Created by wj on 2017/6/25.
*/
/**
* 使用@Service注解声明当前FunctionService类是一个spring管理的一个bean。其中,使用@Componet,@Service,@Repository和@Controller
* 是等效的,可根据需要选用
*/
@Service
public class FunctionService {
public String sayHello(String word){
return "Hello " + word +" !";
}
}
2,使用功能类的bean代码如下:
package jack.ch1.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by wj on 2017/6/25.
*/
//使用@Service声明当前UseFunctionService类是一个spring管理的bean
@Service
public class UseFunctionService {
/**
* 使用 @Autowired将FunctionService的实体bean注入到UseFunctionService中,让UseFunctionService具备FunctionService
* 的功能,此处使用JSR-330的@Inject注解或者JSR-250的@Resource注解是等效的
*/
@Autowired
FunctionService functionService;
public String sayHello(String word) {
return functionService.sayHello(word);
}
}
3,配置类的代码如下:
package jack.ch1.bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Created by wj on 2017/6/25.
*/
//@Configuration声明当前类是一个配置类
@Configuration
//使用@ComponentScan自动扫描包名下所有使用@Service,@Component,@Repository和@Controller的类,并注册为bean
@ComponentScan("jack.ch1.bean")
public class SpringConfig1 {
}
4,编写主类,进行测试:
package jack.ch1.bean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Created by wj on 2017/6/25.
*/
public class MainTest1 {
public static void main(String [] args){
//AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig1.class);
//获取的声明的UseFunctionService的Bean
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);
System.out.println(useFunctionService.sayHello("world"));
context.close();
}
}
运行结果如下:
注意:上面使用@Service注解的时候都没指定bean的名字,默认是该类首字母小写就是spring管理该bean的名字,通过名字进行依赖注入,比如
FunctionService
在spring中的bean的名字就是functionService,这样在下面才能进行依赖注入:
@Autowired
FunctionService functionService;
二:spring中基于java的配置
java配置是spring4.x推荐的配置方式,可以完全代替xml配置;java配置也是spring boot推荐的配置方式。
java配置是通过@Configuration和@Bean来实现的:
@Configuration声明当前类是一个配置类,相当于一个spring配置的xml文件
@Bean注解在方法上,声明当前方法的返回值为一个bean
在springboot的文章中,使用java配置和注解混合配置。何时使用java配置或者注解配置?原则就是:全局配置使用java配置(如数据库相关配置,mvc相关配置),业务bean的配置使用注解配置(@Service,@Component,@Repository,@Controlle)
下面是使用java配置的简单案例:
package jack.ch1.bean;
import org.springframework.stereotype.Service;
/**
* Created by wj on 2017/6/25.
*/
/**
* 使用@Service注解声明当前FunctionService类是一个spring管理的一个bean。其中,使用@Componet,@Service,@Repository和@Controller
* 是等效的,可根据需要选用
*/
//@Service 不使用注解,不需要@Service声明bean
public class FunctionService {
public String sayHello(String word){
return "Hello " + word +" !";
}
}
下面是使用功能的类:
package jack.ch1.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by wj on 2017/6/25.
*/
//使用@Service声明当前UseFunctionService类是一个spring管理的bean
//@Service 不使用@Service声明bean
public class UseFunctionService {
/**
* 使用 @Autowired将FunctionService的实体bean注入到UseFunctionService中,让UseFunctionService具备FunctionService
* 的功能,此处使用JSR-330的@Inject注解或者JSR-250的@Resource注解是等效的
*/
//@Autowired 不使用注解进行依赖注入
FunctionService functionService;
/**
* s使用set方法进行依赖注入
* @param functionService
*/
public void setFunctionService(FunctionService functionService) {
this.functionService = functionService;
}
public String sayHello(String word) {
return functionService.sayHello(word);
}
}
下面是配置类:
package jack.ch1.bean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Created by wj on 2017/6/25.
*使用@Configuration注解声明当前类是一个配置类,着意味着这个类里面可能有0个或者多个@Bean注解
* 此处没有使用包扫描,是因为所有的bean都在此类中定义了
*
*/
//@Configuration声明当前类是一个配置类
@Configuration
public class JavaConfig {
/**
* 使用@Bean注解声明当前方法functionService的返回值是一个Bean,Bean的名称是一个方法名
* @return
*/
@Bean
public FunctionService functionService(){
return new FunctionService();
}
/**
* 使用@Bean注解声明当前方法functionService的返回值是一个Bean,Bean的名称是一个方法名
* @return
*/
@Bean
public UseFunctionService useFunctionService(){
UseFunctionService useFunctionService = new UseFunctionService();
//注入FunctionService的Bean时候直接调用functionService方法
useFunctionService.setFunctionService(functionService());
return useFunctionService;
}
/**
* 使用另外一种方法注入bean,直接将FunctionService作为参数给useFunctionService,这也是
* spring容器提供的极好的功能。在spring容器中存在某个Bean,就可以在另外的Bean的声明方法的参数中注入
*/
/*@Bean
public UseFunctionService useFunctionService(FunctionService functionService){
UseFunctionService useFunctionService = new UseFunctionService();
useFunctionService.setFunctionService(functionService);
return useFunctionService;
}*/
}
下面是测试代码:
package jack.ch1.bean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Created by wj on 2017/6/25.
*/
public class MainTest2 {
public static void main(String [] args){
//AnnotationConfigApplicationContext作为spring容器,接受一个配置类作为参数,使用java配置的bean
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
//获取的声明的UseFunctionService的Bean
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);
System.out.println(useFunctionService.sayHello("world,这是使用java配置生成的bean"));
context.close();
}
}
测试结果: