纯注解方式搭建Spring入门工程

Spring主要有两大核心功能:DI(依赖注入,貌似也叫IOC,即控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)。在相当长时间里Spring的使用和XML配置文件密不可分,复杂的XML配置文件往往使初学者十分头大。XML配置文件书写的时候比较繁琐,并且写错不易排查。近年来,比较新的Spring框架(大概是从Spring3.1开始,Spring4、5肯定是支持注解)支持甚至推荐使用注解的方式进行配置。本文使用JDK1.8和Spring Framework5,以全注解的形式搭建简单的入门工程,对Spring的两大核心功能进行简要介绍。

  1. DI(依赖注入)

下面简要说一下DI的目的和功能。DI的目的是什么?应用程序中的多个类之间通常有依赖关系,即一个类可能持有另一个类的引用,甚至多个类都持有某一个类的引用。那么当这个被引用的类需要修改的时候,相关的类代码可能需要相应地进行修改。依赖注入的一个重要目的就是将类与类之间这种较强的关联、绑定关系变成通过Spring控制的更灵活的对应关系。

Spring推荐使用Maven等工具导入需要的jar包。曾经一度官网上都不提供Spring Framework的jar包(现在也很难找官方下载链接)。但Maven需要连接互联网或者其他Maven源,而且Maven工具本身也有一定的学习成本。此外Maven自动将依赖的jar包下载到.m2/路径下各个单独的文件夹中,不容易搞清楚到底依赖了哪些jar包,也不容易将依赖jar包整理到一起。所以接下来我们使用普通的java工程,通过导入相关jar包的方式来使用Spring。

首先下载Spring Framework5的压缩包,地址:https://repo.spring.io/release/org/springframework/spring/

Spring的官网上没有链接,目前可以通过百度搜索“spring jar”来获取上述下载链接。

下载并解压后,内容如下:

其中需要使用的jar包都在libs目录下,DI主要用到aop、core、beans、context、expression和jcl共6个jar包,前5个是Spring的一些基础功能。此外使用Spring还需要依赖common-logging的jar包(在Spring 4以前,需要单独去下载)。从Spring 4开始,common-logging的内容被包含在spring-jcl中,即上述第6个jar包。注意到每个名字都有.jar、-sources.jar和-javadoc.jar三个jar包,后面会详细介绍分别怎么使用。

使用Eclipse IDE,新建普通java工程:

选中新建的工程,右键选择Properties(或者Alt+Enter)打开工程的属性配置:

Java Build Path -> Add External JARs…,选择上述前5个jar包+common-logging(也可以使用spring-jcl.jar),spring的jar包要引入.jar而不是-javadoc或-sources,下面再介绍这两个怎么用。这里如果导不全通常会报ClassNotFoud的错。

Apply,然后Apply and Close。-sources.jar和-javadoc.jar的使用方法如下:选中jar包(如spring-aop-5.1.2.RELEASE.jar),右键选择Properties(或者Alt+Enter)打开工属性配置:

分别附加源码和javadoc文档,之后鼠标停留在关键词处可以获取查看源码或文档的提示。上述附加源码和javadoc文档的操作不是必须的,略过此步骤不影响功能。

为使用依赖注入功能,最少需要建立两个类才能够成依赖关系。如下创建Person和Torch两个类,Person类中持有Torch类的引用。

package DI;

import java.util.Arrays;
import javax.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component          //标注Bean
public class Person {
	
	@Resource       //实现自动装配,也可以使用@Autowired
	private Torch torch;
	
    //@Autowired
	public void setTorch(Torch t){
		torch = t;
	}
	public void useTorch(){
		torch.light();
	}
	
	public static void main(String[] args) {
		
		AnnotationConfigApplicationContext acx = new AnnotationConfigApplicationContext();
		acx.scan("DI");   //自动扫描的包名要和工程结构相匹配
		acx.refresh();
		
		System.out.println(Arrays.toString(acx.getBeanDefinitionNames()));
		
		Person li = (Person) acx.getBean("person");
		li.useTorch();
		
	}

}

使用@Component表明该类作为组件交给Spring框架来管理,@Resource或@Autowired表明依赖关系,实现自动注入。@Resource或@Autowired可以标注在属性、setter和constructor上。

package DI;

import org.springframework.stereotype.Component;

@Component
public class Torch {
	public void light(){
		System.out.println("Light is here");
	}
}

运行效果如下:

前面几行是对应System.out.println(Arrays.toString(acx.getBeanDefinitionNames()));输出的结果。通过AnnotationConfigApplicationContext进行Context的初始化,然后通过Context获取指定的对象,(类)对象内部依赖的对象由Spring自动初始化并“注入”。

Spring对象默认的是单例模式,即应用运行期间每个类只有一个对象,复杂的配置这里暂不介绍。

  1. AOP(面向切面编程)

下面说一下AOP,切面向切面编程。啥是切面,就是许多个类都会涉及的操作,抽象出来,单独放在一个代码文件中,避免代码重复。个人理解相当于个全局函数,或者静态函数。但Spring面向切面编程要更进一步,依然是通过配置降低切面使用类与切面类之间的关联度。

使用注解方式实现AOP的功能,需要依赖AspectJ相关jar包,在上述工程的基础上至少需要导入aspectjweaver.jar(下面截图的jar包部分有点问题,aspectjrt.jar、aspectjtools.jar其实是不需要的,aspectjweaver.jar没截出来)。AspectJ的jar包需要单独去下载。

新建aop包,以及以下4个文件:

其中切面主要在Audience类里定义,Performance就普通接口,后面的切面操作的切入点是以该接口为基础来定义的。

package aop;

public interface Performance {
	public void perform();
}

ConcertConfig类是个配置类,这个类必须得有,没有的话会报错。三个注释指定该类为配置类、启用切面自动代理以及自动扫描。

package aop;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
	
	@Bean
	public Audience audience() {
		return new Audience();
	}
}

Audience类是定义切面的关键。@Aspect注解表明该类是个切面类,@Pointcut注解定义切入点。通过@Before和@After等注解定义切入点相关的切面操作。

package aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Audience {
	
	@Pointcut("execution(** aop.Performance.perform(..))")
	public void performance() {}
	@Before("performance()")
	public void silenceCellPhones() {
		System.out.println("Silencing cell phones");
	}
	
	@After("performance()")
	public void leave() {
		System.out.println("Going home~~!");
	}

}

Concert类是Performance接口的实现,使用前一节中介绍过的@Component注解及标示类并且使用@Scope注解来指定类型。之前讲过,不指定的话默认是单例模式。这里指定为原型模式的话,大概含义每次需要该类的对象的时候都新创建一个。

package aop;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Concert implements Performance {

	@Override
	public void perform() {
		System.out.println("Concert is performing");

	}
	
	public static void main(String[] args) {
		AnnotationConfigApplicationContext acx = new AnnotationConfigApplicationContext();
		acx.scan("aop");
		acx.refresh();
		
		/*这里注意虽然没有显示去指定ConcertConfig.class作为配置文件,但是其中的配置是生效的,可能源于autoscan*/		
		
		Performance conc = (Performance) acx.getBean("concert");		
		conc.perform();
	}

}

最后运行在内嵌在Concert类中的main函数,得到如下结果:

到此,介绍了搭建最简单的工程实现Spring两大核心功能。我个人学习Spring时入门的最大障碍就是如何快速搭建个工程将Spring的基础功能运转起来,更复杂的功能就可以在此基础上修改、尝试,希望对大家有用。

最后补充一些运行时可能遇到的问题,jdk版本和Spring Framework版本需要匹配,不然会报错。我之前用jdk1.8和Spring Framework3搭配就报ClassNotFoud(凭记忆,不太确定了)的错,换成Spring Framework5就解决了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值