Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。(该概念来源于百度)
IOC(Inverse Of Control):是控制反转,指的是把创建对象的权利和对象生命周期的管理过程交给了Spring;
DI(Dependency Inject):是依赖注入,自动维护对象间的依赖关系。
AOP(Aspect Oriented Programming):是一种面向切面编程的思想,补充了面向对象编程的不足。
是控制反转,指的是把创建对象的权利交给了Spring。实现方式有两种:xml方式和注解方式。
1、创建Maven Module;
2、创建Hello类:
package cn.test.spring;
public class Hello {
public void get(){
System.out.println("hello ioc!");
}
}
3、创建配置文件
在resources文件夹中new——>XML Configuration File——>Spring Config——>新建一个名为spring-config的xml配置文件,用于配置Bean的信息。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="hello" class="cn.test.spring.Hello">bean>
beans>
4、测试
在test文件夹中的java文件夹中新建测试类:
package cn.test.springtest;
import cn.tedu.spring.spring.Hello;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
@Test
public void get(){
/*使用xml方式*/
//1、读取配置文件
ClassPathXmlApplicationContext spring = new ClassPathXmlApplicationContext("spring-config.xml");
//2、直接getBean
Object obj = spring.getBean("hello");
System.out.println(obj);//cn.test.spring.Hello@6a6cb05c
//调用Object的子类Hello的方法——向下转型
Hello h = (Hello)obj;
h.get();// hello ioc!
}
}
1、创建Hello2类
package cn.test.spring2;
//@Component、@Controller、@Service都是spring提供的,都可以用来ioc控制反转
//指定Bean的名字--IOC->{"hello2",new Hello2}
//若只写@Component,不加参数,则默认bean的id为类名首字母变小写
@Component("hello2")
public class Hello2 {
public void get(){
System.out.println("hello ioc2!");
}
}
2、修改配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.test.spring2">context:component-scan>
beans>
3、测试
package cn.test.springtest;
import cn.tedu.spring.spring.Hello2;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
@Test
public void get(){
/*使用xml方式*/
//1、读取配置文件
ClassPathXmlApplicationContext spring = new ClassPathXmlApplicationContext("spring-config.xml");
//2、直接getBean
Hello2 h = (Hello2)spring.getBean("hello2");
System.out.println(h);//cn.test.spring2.Hello2@78123e82
h.get();//hello ioc2!
}
}
是依赖注入,自动维护对象间的依赖关系。
1、创建部门类——Dept类
package cn.test.spring;
public class Dept {
String name="Java软件开发部";
@Override
public String toString() {
return "Dept{" +
"name='" + name + '\'' +
'}';
}
}
2、创建员工类——Emp类
package cn.test.spring;
public class Emp {
String name="Jack";
//绑定两个类间的关系
private Dept d;
//获取Dept对象的get/set方法
public Dept getD() {
return d;
}
public void setD(Dept d) {
this.d = d;
}
@Override
public String toString() {
return "Emp{" +
"name='" + name + '\'' +
", d=" + d +
'}';
}
}
3、测试
package cn.test;
import cn.test.spring.Dept;
import cn.test.spring.Emp;
import org.junit.jupiter.api.Test;
public class Test1 {
@Test
public void di(){
//di 把两个对象间的关系进行依赖注入
//创建dept对象
Dept d = new Dept();
System.out.println(d);//Dept{name='Java软件开发部'}
//创建emp对象
Emp e = new Emp();
System.out.println(e);//Emp{name='Jack', d=null}
//联系两者关系
e.setD(d);
System.out.println(e);//Emp{name='Jack', d=Dept{name='Java软件开发部'}}
}
}
1、创建狗狗类——Dog类
package cn.test.spring2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Dog {
String name = "奥斯卡";
@Autowired
Breed breed;
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", breed=" + breed +
'}';
}
}
2、创建品种类——Breed类
package cn.test.spring2;
import org.springframework.stereotype.Component;
@Component
public class Breed {
String name = "二哈";
@Override
public String toString() {
return "Breed{" +
"name='" + name + '\'' +
'}';
}
}
3、配置包扫描
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.test.spring2"/>
beans>
4、测试
package cn.test;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
@Test
public void getdi(){
//读取xml文件
ClassPathXmlApplicationContext spring = new ClassPathXmlApplicationContext("spring-config.xml");
//getBean
Object dog = spring.getBean("dog");
System.out.println(dog);//Dog{name='奥斯卡', breed=Breed{name='二哈'}}
}
}
AOP(Aspect Oriented Programming面向切面编程):是一种面向切面编程的思想,补充了面向对象编程的不足。
实现的效果:
对方法的增强,本质上就是在执行方法的前后添加功能。
使用场景:
统计性能分析、权限管理、事务管理、日志、缓存等。
切面:
本质上就是一个类;
通知:
本质上就是一个方法,分为:前置通知、后置通知、环绕通知、返回后通知、异常通知;
前置通知:是方法执行前要执行的功能;
后置通知:是方法执行后要执行的功能;
环绕通知:是方法执行前后都要执行的功能。
切点:
指定哪些类里的哪些方法要用通知的功能
常用AOP注解:
@Aspect:表示是一个切面类;
@Before:表示是一个前置通知;
@After:表示是一个后置通知;
@Around:表示是一个环绕通知;
@Pointcut:表示切点
1、导入jar包
添加aop的jar包
2、测试
(1)创建三个包:controller、pojo、service三个包,并放在同一个包下。
(2)导入jar包:lombok和aop
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.20version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
(3)新建RunApp类,注意该类必须放在controller、pojo、service三个包的同一级包下
package cn.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class,args);
}
}
(4)在pojo包下创建Car类
package cn.test.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Car {
private Integer id;
private String name;
private String color;
private Double price;
}
(5)在service包下创建一个接口CarService
package cn.test.service;
import cn.test.pojo.Car;
public interface CarService {
Car get();
String buy();
}
(6)在service包下创建CarService接口的实现类CarServiceImpl
package cn.test.service;
import cn.tedu.pojo.Car;
import org.springframework.stereotype.Service;
/*CarService接口的实现类*/
@Service
public class CarServiceImpl implements CarService{
@Override
public Car get() {
Car c = new Car();
//lombok的链式编程
c.setName("保时捷").setColor("红色").setPrice(2333333.3);
return c;
}
}
(7)在service包下创建aop的类,以环绕通知@Around为例。
package cn.test.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
@Service//完成IOC
@Aspect//标记着这是一个aop的类,即切面,由切点和通知组成
public class AopAspect {
//切点:指定具体要用通知的类或方法等
//切点表达式:*是通配符, ..表示多个
//execution(方法返回值 包路径 子包 类名 方法名 参数列表)
@Pointcut("execution( * cn.tedu.service..*.*(..))")
public void point(){
}
//通知:是一个方法自定义功能
//Around:表示一个环绕通知
//参数表示使用上述的切点方法
@Around("point()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
//计时开始
long time = System.currentTimeMillis();
//执行业务代码——joinPoint相当于连接点
//前往去执行你的业务方法
Object o = joinPoint.proceed();
//计时结束,统计时长
time = System.currentTimeMillis() - time;
//获取反射cn.tedu.service包下类 方法的全路径
String methodName = joinPoint.getTarget().getClass().getName() + " . " + joinPoint.getSignature().getName();
System.out.println( methodName + "方法执行时间是:" + time);
return o;
}
}