Spring核心——IOC、DI、AOP

概述

  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):是一种面向切面编程的思想,补充了面向对象编程的不足。

IOC

  是控制反转,指的是把创建对象的权利交给了Spring。实现方式有两种:xml方式和注解方式。

IOC的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!
	    }
	}

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!
	    }
	}

DI

  是依赖注入,自动维护对象间的依赖关系。

普通依赖关系的实现

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软件开发部'}}
    }
}

使用spring注解来实现

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

概述

  AOP(Aspect Oriented Programming面向切面编程):是一种面向切面编程的思想,补充了面向对象编程的不足。
  实现的效果:
   对方法的增强,本质上就是在执行方法的前后添加功能。
  使用场景:
   统计性能分析、权限管理、事务管理、日志、缓存等。
  切面:
   本质上就是一个类;
  通知:
   本质上就是一个方法,分为:前置通知、后置通知、环绕通知、返回后通知、异常通知;
    前置通知:是方法执行前要执行的功能;
    后置通知:是方法执行后要执行的功能;
    环绕通知:是方法执行前后都要执行的功能。
  切点:
   指定哪些类里的哪些方法要用通知的功能
  常用AOP注解:
   @Aspect:表示是一个切面类;
   @Before:表示是一个前置通知;
   @After:表示是一个后置通知;
   @Around:表示是一个环绕通知;
   @Pointcut:表示切点

使用步骤

1、导入jar包
  添加aop的jar包
2、测试
(1)创建三个包:controller、pojo、service三个包,并放在同一个包下。
Spring核心——IOC、DI、AOP_第1张图片
(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;
    }
}

你可能感兴趣的:(Spring)