目录
一、Spring 概述
1、简介
2、搭建 Spring IOC环境
二、Spring对Bean的管理
1、创建bean的方式
2、获取bean的方式
3、bean 对象的生命周期
4、bean 的作用范围
三、Spring 的依赖注入
1、构造函数注入
2、set 注入
3、集合注入
四、Spring 注解配置
1、创建Spring配置文件
2、注解配置
3、Spring 的新注解
五、Spring 中的 AOP
1、AOP概述
2、搭建Spring AOP环境
3、Spring 使用XML配置 AOP
4、环绕通知
六、基于注解的AOP配置
1、配置步骤
2、环绕通知注解配置
3、不使用XML配置
Spring是一个开源的框架,Spring 为简化企业级开发而生,使用 Spring、JavaBean 就可以实现很多以前要靠 EJB 才能实现的功能,同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而使用Spring 却非常的优雅和简洁。
【1】Spring 的核心:
【2】IOC和DI
IOC描述的是一种思想,DI是对IOC思想的具体实现
【3】Spring 优点
【1】创建 maven 版的 Java 工程
搭建好后目录结构如下:
【2】导入 jar 包
在pom.xml中加入相关依赖,导入Spring相关jar包(为了方便后面进行测试,这里导入了测试jar包)
jar
org.springframework
spring-context
5.0.2.RELEASE
junit
junit
4.12
【3】创建 Spring 配置文件
在 resources 目录下创建配置文件,内容如下(可以从Spring官网获取)
【4】创建实体类
创建一个简单的HelloWorld类
public class Helloworld {
private String name;
public Helloworld(){
System.out.println("创建对象");
}
public void setName(String name) {
System.out.println("调用方法");
this.name = name;
}
public void sayHello(){
System.out.println("Hello!" + name);
}
}
【5】对类进行配置
配置之后如下
【6】测试类
public class test {
@Test
public void test(){
//1.创建IOC容器对象
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从IOC容器中获取Helloworld对象
Helloworld hello = (Helloworld) ioc.getBean("helloworld");
//3.调用类中方法
hello.sayHello();
}
}
【1】默认使用构造函数创建
在Spring的配置文件中使用bean标签,配置 id 和 class 属性后,没有其他属性和标签时,采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。
【2】类中的方法创建
很多时候我们会使用某个类中的或者jar包中的方法或者普通工厂中的方法来创建对象,并存入到Spring容器中
【3】类中的静态方法创建
使用某个类中的静态方法创建或者工厂中的或者jar包中的静态方法创建,并存入到Spring容器中
配置文件就是让IOC容器能够来管理一个具体的对象,主要就是通过配置
Class class = Class.forName("com.LSTAR.Helloworld");
Object obj = class.=newlnstance(); //无参构造函数
获取bean有三种方式
【1】根据 id 获取
通过唯一标识 id 来获取,上面的环境搭建就是用的这种方式
Helloworld hello = (Helloworld) ioc.getBean("helloworld");
【2】通过 bean 类型获取
如果同一个类型的bean在xml文件中配置了多个,则获取时会抛出异常,所以同一个类型的bean在容器中必须是唯一的
Helloworld hello = ioc.getBean(Helloworld.class);
【3】指定bean的 id 值和类型
Helloworld hello = ioc.getBean("helloworld",Helloworld.class);
【1】单例对象
单例bean对象随容器共存亡
【2】多例对象
通过bean 标签的 scope 属性来指定 bean 的作用范围,属性值有:
使用构造函数注入,需要在类中创建带参的构造函数,在 bean 标签中使用
使用 set 注入需要在类中创建 set 方法,在 bean 标签中使用
比如:在学校类中除了有年龄,姓名属性,还有老师对象属性,对于年龄、姓名属性可以直接使用 value属性进行赋值,而老师对象则需要通过 ref 进行赋值
使用集合注入,首先在类中创建集合成员变量和set方法,这里创建了String[]数组集合、List集合、Set集合、Map集合、Properties集合,并生成了相应的set和toString方法,接下来对xml配置文件进行bean的配置,配置如下:
oneStar
twoStar
threeStar
oneStar
twoStar
threeStar
oneStar
twoStar
threeStar
oneStar
twoStar
使用Spring注解配置需要需要配置自动扫描的包,让Spring知道配置文件是哪一个,配置如下:
【1】创建对象注解
@Component
@Controller、@Service、@Repository这三个注解的作用和@Component注解是一样的,他们是Spring框架为我们提供明确的三层使用注解,使三层对象更加清晰
【2】注入数据注解
@Value
@Autowired
@Qualifier
@Resource
注:
【3】改变作用范围注解
@Scope
【4】生命周期相关注解
创建一个配置类,用来代替bean.xml 配置文件
【1】@Configuration
【2】@ComponentScan
【3】@Bean
注:当使用注解配置时,如果方法有参数,Spring会去容器中查找有没有可用的bean对象
【4】@Import
【5】@PropertySource
【1】什么是AOP
AOP(Aspect Oriented Programming):面向切面编程,即通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是Spring框架中一个重要的技术,Spring 中的 AOP,就是通过配置的方式,实现动态代理的过程,它是函数式编程的一种衍生范型,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间耦合度降低,提高程序的可重用性和开发效率
【2】AOP作用及优势
【3】AOP 相关术语
【1】创建 maven 版的 Java 工程
首先要准备好必要的代码,这里创建了实体类、业务层和持久层代码,模拟保存、更新、删除账户的功能,并对其进行记录日志的增强,创建好后目录结构如下:
//IAccountService接口
public interface IAccountService {
//模拟保存账户
void saveAccount();
//模拟更新账户
void updateAccount(int i);
//模拟删除账户
int deleteAccount();
}
//AccountServiceImpl 实现类
public class AccountServiceImpl implements IAccountService {
public void saveAccount() {
System.out.println("执行了保存");
}
public void updateAccount(int i) {
System.out.println("执行了更新" + i);
}
public int deleteAccount() {
System.out.println("执行了删除");
return 0;
}
}
//Logger类(增强部分)
public class Logger {
public void printLog(){
System.out.println("滴滴滴,开始记录日志!");
}
}
【2】导入 jar 包依赖
jar
org.springframework
spring-context
5.1.9.RELEASE
org.aspectj
aspectjweaver
1.9.4
【3】创建Spring配置文件并导入约束
【4】配置Spring的IOC
到这里,Spring AOP环境就基本搭建完成,接下来就是Spring在XML(bean.xml)中配置AOP了
【1】配置增强类(通知类)
【2】使用 aop:config 声明 AOP 配置
【3】使用 aop:aspect 配置切面
【4】使用 aop:pointcut 配置切入点表达式
【5】使用 aop:xxx 配置对应的通知类型(具体的增强部分)
【6】切入表达式
关键字:execution(表达式)
实际开发中切入表达式一般切入到业务层实现类下的所有方法:* com.LSTAR.service.impl.*.*(..)
bean.xml文件
环绕通知是 Spring 框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式,spring 框架为我们提供了一个接口:ProceedingJoinPoint,它可以作为环绕通知的方法参数。 * 在环绕通知执行时,spring 框架会为我们提供该接口的实现类对象,我们直接使用就行,使用环绕通知需要在xml配置文件中进行配置
配置方式:在 aop:aspect 标签内部配置
环绕通知方法(增强方法)
public Object aroundPrintLog(ProceedingJoinPoint pjp){
Object reValure = null;
try {
Object[] args = pjp.getArgs(); //得到方法执行所需的参数
System.out.println("滴滴滴,环绕通知开始记录日志!---前置通知");
reValure = pjp.proceed(args); //明确调用业务层方法(切入点方法)
System.out.println("滴滴滴,环绕通知开始记录日志!---后置通知");
return reValure;
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("滴滴滴,环绕通知开始记录日志!---异常通知");
} finally {
System.out.println("滴滴滴,环绕通知开始记录日志!---最终通知");
}
return reValure;
}
【1】配置xml配置命名空间
【2】把对象放入容器中
使用 @Service 和 @Component 注解把实体类和增强类放入 Spring 容器中
【3】配置切面
使用 @Aspect 注解来表示当前类是一个切面
@Service("accountService")
public class AccountServiceImpl implements IAccountService {}
@Component
@Aspect //表示当前类是一个切面
public class Logger {}
【4】切入表达式注解
【5】在增强方法上使用注解
@Component
@Aspect //表示当前类是一个切面
public class Logger {
@Pointcut("execution(* com.LSTAR.service.impl.*.*(..))") //定义切入点表达式
private void pt1(){};
@Before("pt1()")
//@Before("execution(* com.LSTAR.service.impl.*.*(..))")
public void beforeLog(){
System.out.println("前置通知");
}
@AfterReturning("pt1()")
public void afterReturuingLog(){
System.out.println("后置通知");
}
@AfterThrowing("pt1()")
public void afterThrowingLog(){
System.out.println("异常通知");
}
@After("pt1()")
public void afterLog(){
System.out.println("最终通知");
}
}
//@Around("pt1()")
@Around("execution(* com.LSTAR.service.impl.*.*(..))")
public Object aroundPrintLog(ProceedingJoinPoint pjp){
Object reValure = null;
try {
Object[] args = pjp.getArgs(); //得到方法执行所需的参数
System.out.println("滴滴滴,环绕通知开始记录日志!---前置通知");
reValure = pjp.proceed(args); //明确调用业务层方法(切入点方法)
System.out.println("滴滴滴,环绕通知开始记录日志!---后置通知");
return reValure;
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("滴滴滴,环绕通知开始记录日志!---异常通知");
} finally {
System.out.println("滴滴滴,环绕通知开始记录日志!---最终通知");
}
return reValure;
}
@Configuration
@ComponentScan(basePackages="com.LSTAR")
@EnableAspectJAutoProxy
public class XXX{ }