Spring的学习与使用
0 概念
spring是分层的javase/ee应用的轻量级开源框架,以ioc与aop为核心,提供了表现层的springmvc与持久层的jdbc遗迹业务层的事务管理等众多的企业级应用技术,其中还整合了许多的三方类库,功能强大。
1 spring的核心容器IOC
1.1 spring有2大核心容器 IOC与AOP。
IOC(invoke of control):控制反转,将控制权交给了工厂,让工厂来创建对象。优点就是减低耦合。
AOP(aspect oriented pargarm):面向切面编程,把crud操作和日志统计操作编织在一起。
1.2 程序之间的耦合
耦合:程序之间的依赖关系,包括:类之间的依赖关系,以及方法之间的依赖关系。
解耦:降低程序之间的依赖关系。项目执行要求:高内聚,低耦合
如何解耦:
ⅰ用反射来创建对象,避免使用new关键字
ⅱ使用配置文件,通过配置文件来方便代码的编写(即使用工厂模式来创建对象)。
1.3 spring的IOC解决程序直接按的耦合
spring中的IOC解决了程序之间的依赖关系,即不需要自己new对象,把这个交给了spring框架来完成。
2 项目的搭建
首先,idea直接创建一个空的maven工程,将spring的jar包代码导入即可。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
<version>1.16.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
然后,在resources文件夹下面新建一个名为 springbean.xml的文件
<?xml version="1.0" encoding="UTF-8" ?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
</beans>
之后,需要将对象的创建交给spring来完成,即可。以上项目的搭建就算完成了。
3 IOC的xml配置
3.1 利用spring创建对象的方式有3种:
第一种创建方法 使用bean标签,该方法是用类中的默认的构造函数来创建对象,
如果没有默认的构造函数,那么创建就会失败
<bean id="accountService" class="Service.AccountServiceImpl"/>
第二种创建方法 使用普通工厂(就是jar包中的一些类)创建spring容器
<bean id="instanceFfactory" class="factory.InstanceFfactory"/>
<bean id="accountservice" factory-bean="instanceFfactory" factory-method="getinstance"/>
第三种创建方法 使用工厂中的静态方法创建对象
<bean id="accountservice" class="factory.StaticInstanceFfactory" factory-method="getinstance" />
第一种方法的使用:
首先,在上面的springbean.xml中配置需要new的对象,格式如下:
<bean id="accountService" class="Service.AccountServiceImpl"/>
然后在需要new对象的地方使用如下代码:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "springbean.xml" });
accountService account = (accountService) context.getBean("accountService");
System.out.println(account.getName());
}
3.2 bean的作用范围
Singleton:单例模式(默认值)
Prototype:多例的
Request:与web中的应用范围一样
Session:同上
Golabe-session:用于服务器集群
3.3 bean的生命周期
单例:当容器创建时,对象就被创建了,容器销毁,单例也就结束了。即单例模式的生命周期和容器的生命周期相同。
多例:当使用的时候,spring框架帮我们创建,对象只要被使用就一直存活,当对象长时间不使用的时候,就会由java的垃圾回收机制GC来释放他。
4 依赖注入DI
依赖注入(Dependence Inject),简单地说就是拿到的对象的属性,已经被注入好相关值了,直接使用即可。
问:那些对象能够注入?
答:能够注入的数据类型有①基本数据类型与string,②类对象,③复杂类型/集合类型
问:有那些注入的方式呢?
答:三种注入方式①构造函数提供,②set方法,③注解提供
C01 构造函数的注入 类中必须存在构造方法
C02 set方法的注入 类中必须存在set方法
C03 复杂类型参数的注入,如list,map,set,porperties等
5 Spring中注解配置
常用的类配置标签:
<bean id="accountService" class="Service.AccountServiceImpl" scope="">
<property name="" value="">
</property>
</bean>
5.1 常用注解分类
A 创建对象的注解,功能就和bean标签相同
B 注入数据的注解,功能就和bean标签下的property标签相同
C 改变作用范围的注解,功能就和bean标签下的scope相同
D 与生命周期相关的注解,功能就和bean标签下的init-method等相同
5.2 注解详解
A类注解 | 作用 | 用例 |
---|---|---|
@Component | 类注解,将当前类对象存入spring的容器中,与bean标签功能相同,默认的id值为当前类名的首字母小写。 | 在实体类上面可以添加 |
@Controller | 表现层注解 | |
@Service | 业务层注解 | |
@Repository | 持久层注解 |
B类注解 | 作用 | 用例 |
---|---|---|
@Autowired | 自动按照类型注入,只要容器中有唯一的bean类型与变量的数据类型相匹配,就可以注入成功,如果有多个类型相匹配,搜先按照类型进行匹配对象,再根据变量名称作为bean的id,查找是否有相同的,有就成功注入,没有就失败报错。 | |
@Qualifier | 在类的注入基础上,在按照名称注入,在类上不能单独使用,但是在方法上可以。 | 下图上 |
@Resource | 直接按照类的id注入,能够独立使用,属性为name,而不是value。 | 下图下 |
@Value | 用于注入基本类型和string类型的数据,属性value用于指定数据的值,可以使用spEL(spring的el表达式,其写法为${表达式})。 |
C01 @Scope注解
作用:指定bean的作用范围。属性value的取值一般为singleton与protoype。不写就是默认为单例模式的。
D01 @PreDestory注解
作用:用于指定销毁的方法,
D02 @init-method注解
作用:用于指定初始化的方法
6 Spring的核心容器Aop
面向切边编程,首先需要明白切点和切面是什么,切点即需要执行的业务主方法,如登陆操作,切面即主方法之外的辅助功能,例如登陆操作时向日志输入一句“xxx登陆了”的功能。
这就是aop思想,将主要功能与辅助功能区分开来,他们相互不影响,但是相互依存 。
6.1 在xml中配置切面
a 将辅助功能类bean交给spring来管理。
b 使用aop:config标签来表名aop开始配置
c 使用aop:aspect标签来配置切面(辅助功能),其中标签内的id属性是给切面提供一个唯一标识符,ref属性指定辅助功能类bean的id(就是使用这个类中的方法来进行辅助功能操作的)。
d 在aop:aspect标签下使用对应的配置标签来配置具体的操作。(是在主方法业务执行前执行功能类中的方法,还是之后等)。
<bean id="test1" class="Test11.Test1"/>
<aop:config>
<aop:aspect id="testaop" ref="test1" >
<aop:before method="sayhello" pointcut="execution(public void Service.AccountServiceImpl.saveaccount())" />
</aop:aspect>
</aop:config>
Aop:before 配置前置通知。Method:调用功能类中的那个方法。
Pointcut属性:即切入点表达式(就是指对那些主方法进行加强)
写法:pointcut=“excute(修饰符 返回值类型 包名下的类名中的方法((参数列表))”
6.1.1 切入点表达式的写法
pointcut="execution(public void Service.AccountServiceImpl.saveaccount())"
全通配写法:* ….*(…)
public 访问修饰符可以省略,返回值可以使用通配符星号* 代表所有的返回值。包名也可以使用*代替。类也是,方法也是。
void 参数类型:基本数据类型直接写,引用数据类型写包名加上类名,也可以使用通配符来代替任意类型,但是必须有参数才可以。使用。。(点点)有参无参。
Service.AccountServiceImpl.saveaccount() 具体的是监控哪一个业务(方法)。必须写上全类名。
简化写法:使用配置切入点表达式:多次书写比较麻烦,相当于给他起个名字了。
<aop:pointcut id=”将要被应用的值” expression=”execution(xxxxxx)”>
然后在配置通知的时候使用pointcut-ref标签进行引入。
同时需要注意使用范围,如果配置在aop:aspect内部,就只能在内部使用,配置在外部就变成全局可以使用了。
6.2 基于注解的aop配置
在spring的配置文件中,加上此句:<aop:aspectj-autoproxy />用于开启aop的注解配置。