1、Spring 有两个核心部分:

IOC 和 Aop (1)IOC:控制反转,把创建对象过程交给 Spring 进行管理

       (2)Aop:面向切面,不修改源代码进行功能增强

2、Spring 特点:

(1)方便解耦,简化开发

(2)Aop 编程支持

(3)方便程序测试

(4)方便和其他框架进行整合

(5)方便进行事务操作

(6)降低 API 开发难度

3.IOC(控制反转)

IOC是什么

IOC:控制反转,也叫依赖注入,他就是不会直接new出对象,是把对象声明出来,在代码中不直接与对象和服务直接进行连接,

   但是在配置文件中描述乐力那一项组件需要哪一项服务,可以通过容器(bean.xml)将他们组装起来来。在一般的IOC场景中容器创建了所有的对象,

   并设置了必要的属性将他们联系在一起,等到需要使用的时候才把他们声明出来。

 3.1.Spring 提供 IOC 容器实现两种方式:(两个接口)

(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口(加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象)不建议使用

(2)ApplicationContext:BeanFactory 接口的子接口( 加载配置文件时候就会把在配置文件对象进行创建)

public static void main(String[] args) {
        //1.加载spring配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取配置创建的对象
        User user = context.getBean("user", User.class);
        System.out.println("user = " + user);
        user.add();
    }

3.2.bean 生命周期

(1)通过构造器创建 bean 实例(无参数构造)

(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)

(4)bean 可以使用了(对象获取到了)

(5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

3.3.用注解方式实现对象创建

(1)引入依赖:spring-aop-5.2.6.RELEASE.jar

(2)开始组件扫描:

    基于bean.xml配置文件中

<context:component-scan base-package="com.spring5.aopanno"></context:component-scan>

    基于注解

@Configuration//作为配置类,替代xml配置文件
@ComponentScan(basePackages = {"com.spring5"})//开始注解扫描
@EnableAspectJAutoProxy(proxyTargetClass = true)//开启Aspect生成代理对象
public class ConfigAop {}

(3)使用注解

   @Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的 组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。(用于pojo的注入)

   @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IOC 容 器中。(用于注入服务)

      @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以 在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。(用于Service的注入)

      @Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了 额外的好处。它将 DAO 导入 IOC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。(用于dao的注入)

  上面四个注解功能是一样的,都可以用来创建 bean 实例

@Service
public class UserService {
 }

 

    @Autowired:根据属性类型进行自动装配

public class UserService {
 //不需要添加 set 方法
 //添加注入属性注解
 @Autowired 
 private UserDao userDao;
 public void add() {
 System.out.println("add.......");
 userDao.add();
 }
}

    @Resource:可以根据类型注入,可以根据名称注入

//@Resource //根据类型进行注入
@Resource(name = "userDaoImpl") //根据名称进行注入
private UserDao userDao;

    @Value:注入普通类型属性

@Value(value = "abc")
private String name;

(4)编写测试类

@Test
    public void testAop(){
        ApplicationContext context = new AnnotationConfigApplicationContext(ConfigAop.class);
        User user = context.getBean("user",User.class);
        System.out.println(user);
        user.add();
    }

4.Aop

4.1.AOP是什么

AOP:   面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,

    抽取并封装为一个可重用的模 块,这个模块被命名为“切面”,减少系统中的重复代码,降低了模块间的耦合度,

    同时提高了系统的可维护性。可用于权限认证、日志、事务处理等。

4.2.AOP(术语)

1.连接点:类里面有哪些方法可以被增强,这些方法称为连接点

//被增强的类
@Component//连接点
public class User {
    public void add(){
//        int i=10/0;
        System.out.println("add.....");
    }
}

2.切入点:实际被真正增强的方法,称为切入点

//    切入点
    //(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
    //(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )
    //  *   表示所有的仿修饰符
//相同切入点抽取
@Pointcut(value = "execution(* com.spring5.aopanno.User.add(..))")
public void pointdemo() {
}

3.通知(增强):实际增强的逻辑部分称为通知(增强)/(切面的工作被称为通知)

  (1). 前置通知(@Before):在目标方法被调用之前调用通知功能;

@Before(value = "pointdemo()")
    public void before() {
        System.out.println("User........before.........");
    }

 

  (2).  后置通知 / 返回通知(@AfterReturning ):在目标方法成功执行之后调用通知;

@AfterReturning(value = "pointdemo()")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

  (3). 最终通知(@After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;

@After(value = "pointdemo()")
    public void after() {
        System.out.println("after.........");
    }

  (4). 异常通知(@AfterThrowing):在目标方法抛出异常后调用通知;

@AfterThrowing(value = "pointdemo()")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

  (5). 环绕通知(@Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行 自定义的行为。

@Around(value = "pointdemo()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前.........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.........");
    }

4.3.其他注解

@Order(1):设置优先级,值越小优先级越高

@Component  //创建 bean 实例
@Aspect     //生成代理对象
@Order(1)   //设置优先级,值越小优先级越高
public class PeopleProxy {
    @Before(value="execution(* com.spring5.aopanno.User.add())")
    public void before(){
        System.out.println("People........before............");
    }
}