初识spring

本文详细介绍了Spring框架中的IoC(控制反转)、DI(依赖注入)以及AOP(面向切面编程)的概念和实现方式。通过XML配置和注解两种方式展示了IoC和DI的使用,解释了依赖注入的@Autowired注解的工作原理。此外,还探讨了AOP的组成,包括切面、切点和通知,并通过环绕通知的示例展示了AOP在实际应用中的功能。
摘要由CSDN通过智能技术生成

Spring

1. IoC控制反转

IOC(Inversion of Control),控制反转。
就是指将对象的创建,对象的存储(map),对象的管理(依赖查找,依赖注入)交给了spring容器。

1. 1xml配置IoC

创建hello类

package cn.tedu.pojo

public class Hello() {
	public void hi() {
		System.out.println("hi spring ioc");
	}
}

创建spring-config.xml文件

<!-- 在框架里开始了ioc ,会把每个类创建对象,并存起来 Map<id的值,对象>
        Map<String,Object> 存的是 {"hello" = new Hello()}
        框架只会拿到class文件,需要反射创建对象:
        {"hello" = Class.forName("cn.tedu.pojo.Hello").newInstance() }
-->
<bean class="cn.tedu.pojo.hello" id="hello"></bean>

创建测试类

@Test
public void ioc() {
	//读取核心配置文件
	ClassPathXmlApplicationContext spring =
		new ClassPathXmlApplicationContext("spring-config.xml");
	//根据核心配置文件中,id属性的值,获取对应对象
	Object o = spring.getBean("hello");
	Hello h = (Hello)o;
	h.hi();
}

1.1 注解IoC

@Componet注解

spring框架提供,用来完IoC,存入map{ “person” = new Person() }

创建Person类

package cn.tedu.pojo

@Component
public class Person() {
	public String name = "djh";
}

配置扫描器

配置扫描器是为了让spring框架知道哪些类上面使用了@Component注解,指定扫描那个包里的资源

<context:component-scan base-package="cn.tedu.pojo"></context>

扫描cn.tedu.pojo本包及子包带@Component注解的类

创建测试类

@Test
public void iocanno() {
	//读取核心配置文件
	ClassPathXmlApplicationContext spring =
		new ClassPathXmlApplicationContext("spring-config.xml");
	//获取spring框架new的对象,根据类名首字母小写为条件获取对象
	Person p = (Person)spring.getBean("person");
	//调用子类的资源
	System.out.println(p.name);
}

2. DI依赖注入

DI(Dependency Injection)依赖注入 。

相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。

@Autowired注解

利用注解方式,我们只需要写@Autowired注解,底层就会去容器中找对应的对象,如果有获取到,反射调用其对应的set方法,设置。而这个调用过程都是自动,我们没有手工去写set方法。所以这个过程也称为自动装配

Dept.java

package spring.pojo;

import org.springframework.stereotype.Component;

@Component
public class Dept {
    public String deptName = "软件部";
}

User.java

package spring.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class User {
    //相当于框架完成了:new User().setDept(new Dept());
    @Autowired
    private Dept dept;   //对象的关联
    public String name = "tony";
}

测试DI

package test;

import org.springframework.context.ApplicationContext;
import	org.springframework.context.support.ClassPathXmlApplicationContext;


import spring.pojo.Dept;
import spring.pojo.User;

public class TestDI {
    public static void main(String[] args) {
       ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
       Dept d = (Dept)ac.getBean("dept");
       User u = (User)ac.getBean("user");     
       System.out.println(d);
       System.out.println(u);      
       System.out.println(u.getDept().deptName);
    }
}
@Autowrie注解描述属性时,注入规则:

spring框架会依据@Autowrie注解描述的类型属性,从spring容器中查找对应的Bean,假如只找到一个则直接注入,假如找到多个还会比对属性名是否与容器中的Bean的名字有相同的,有则直接注入,没有则抛出异常

3. AOP面向切面编程

Spring核心特征中除了IoC控制反转、DI依赖注入,还有一个核心就是强大的面向切面编程AOP(Aspect Oriented Programming)的实现。Spring的AOP功能,其实就是为了增强方法的功能,AOP的使用场景:事务管理、权限管理、缓存管理、日志管理、性能测试。

3.1 组成

切面Aspect

其实就是一个类,由通知和切点组成,创建一个类,用@Aspect注解标记是一个切面

@Aspect
public class AspectTest {

}
切点PointCut

1.使用@Pointcut注解,需要写切点表达式, 切点表达式用来给指定包,类,方法加功能,execution的参数规则如下:
(返回值 包名.类名.方法名(参数列表))

 @Pointcut("execution(* cn.tedu.service..*.*(..))")

*通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词
…通配符,该通配符表示0个或多个项

通知Advice

就是类里的一个方法,分为:
①前置通知before(方法执行前要加的)
②后置通知after(方法执行后要加的)
③环绕通知around(方法执行前后都要加的)
④返回后通知afterReturning
⑤异常通知afterThrowing

3.2 测试环绕通知
package cn.tedu.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.Component;

@Component
@Aspect //标记是一个切面
public class AspectTest {
    @Pointcut("execution(* cn.tedu.service..*.*(..))")
    public void point() {}

    //定义通知,本质就是一个方法,增强功能
    @Around("point()")//标记环绕通知,方法执行前后都加功能
    public Object doAround(ProceedingJoinPoint joinPoint) throws  Throwable {
        long startTime = System.currentTimeMillis();
        Object object = joinPoint.proceed();//继续执行原来的业务
        long endTime = System.currentTimeMillis();
        System.out.println("aop计算的耗时是:"+(endTime-startTime));
        //返回这个结果
        return object;
    }
}

执行结果:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卑微前端汪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值