栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring总结(spring基础)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring总结(spring基础)

Spring 学习笔记 1、spring 概述

什么是spring

用鱼皮(一个程序员up主)给出思维导图中对spring的描述:Java 轻量级应用框架

spring 要学哪些内容

你去搜索spring该如何学习的话,或者在spring 官网中找的话,逃不开两个术语,IOC 和 AOP,所以,得学

IOCAOP 2、IOC (控制反转)

IOC 理念推导

假设一个场景要获取用户的数据。

按照mvc三层架构,编写model层代码。

1、UserDao接口

package com.company.dao;

public interface UserDao {
    //获取用户测试
    public void getUser();
}

2、UserDaoImpl 实现类

package com.company.dao;

public class UserDaoImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("模拟实现获取了用户的数据");
    }
}

3、UserService 接口

package com.company.service;

public interface UserService {
    public void getUser();
}

4、UserServiceImpl 业务实现类

package com.company.service;

import com.company.dao.UserDao;
import com.company.dao.UserDaoImpl;

public class UserServiceImpl implements UserService{

    private UserDao userDao = new UserDaoImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

5、代码测试

// 使用junit单元测试
@Test
public void test() {
    new UserServiceImpl().getUser();
}

6、结果演示

7、问题提出,思考,如果我们添加了一个UserDaoMySqlImpl类的话

package com.company.dao;

public class UserDaoMySqlImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("默认获得了MySql用户的数据");
    }
}

程序该如何调度这个类里面的方法执行呢? 没错,在UserServiceImpl里面改变userDao的指向

package com.company.service;

import com.company.dao.UserDao;
import com.company.dao.UserDaoImpl;

public class UserServiceImpl implements UserService{

    private UserDao userDao = new UserDaoMysqlImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

结果演示:

如果程序有成千上万个Dao的实现类呢?而且不同地方指定不同的实现类呢?难道我们要每次跑到ServiceImpl里面去修改指向吗?

那肯定是不能的,代码量十分大,修改一次的成本是很昂贵的,那有什么办法可以较好的解决这个问题呢?见如下代码

package com.company.service;

import com.company.dao.UserDao;
import com.company.dao.UserDaoImpl;
import com.company.dao.UserDaoMysqlImpl;
import org.junit.Test;

public class UserServiceImpl implements UserService{
   private UserDao userDao;

   // 在这里添加一个setter方法
   public void setUserDao(UserDao userDao) {
       this.userDao = userDao;
   }

    @Override
    public void getUser() {
        userDao.getUser();
    }


    @Test
    public void test() {
        UserServiceImpl userService = new UserServiceImpl();
        // userService.setUserDao(new UserDaoImpl());
        userService.setUserDao(new UserDaoMysqlImpl());
        userService.getUser();
    }
}

IOC 程序从主动的创建对象 变成了 被动的接收对象

这种思想,从本质上解决了问题,我们程序员不需要再去管理对象的创建了,系统的耦合性大大降低,可以更加专注的去实现业务。

这是IOC的原型!

还有课外阅读,有不明白IOC的小伙伴可以看下。

大牛文章写的很不错,这里直接贴出源地址。IOC 理解:https://zhuanlan.zhihu.com/p/64001753

我这里只讲述自己阅读文章时觉着很恍然大悟的地方。

而在实际应用中,myApp.jar中往往包含了程序主流程。而主流程一旦完成,就应该保持相对稳定。如果有改变,也应该通过扩展的方式。这也就是架构设计中著名的“开关原则”,即主业务对修改关闭,对扩展开放。而使用Spring就可以达到这样的目的。

3、第一个spring程序

1、导包 使用spring开发web项目需要导入的包


    org.springframework
    spring-webmvc
    5.3.9

2、编写applicationContext.xml 配置文件




    
    
    
    
        
    

3、代码执行

import com.company.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 获取Spring的上下文对象(同时也是IOC容器)
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Hello hello = (Hello)context.getBean("hello");
        // 这个等同于上面这句话
        //Hello hello = context.getBean("hello",Hello.class);
        System.out.println(hello);
    }
}

4、结果演示:

4、IOC 创建对象

1、首先创建一个实体类

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// 使用lombok 需要导入lombok的依赖, 具体依赖请搜索maven repository中的lombok
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
}

2、编写application.xml 文件

使用无参构造创建对象


改写User类中的无参构造

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor

public class User {
    private String name;

    public User() {
        this.name = "qizai";
    }
}

结果输出

使用有参构造创建对象


    

代码测试

import com.company.pojo.Hello;
import com.company.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 获取Spring的上下文对象(同时也是IOC容器)
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        User user = context.getBean("user", User.class);

        System.out.println(user);
    }
}

结果演示:

这个标签里面还有几个属性讲解一下

其实就是思考一下,已经指定为有参构造了,我们要传参,如何定位到类的成员变量

第一种,像上面那样,指定成员变量的名字

第二种,使用下标确定成员变量

代码演示


    

结果演示

第三种,使用参数类型(不具有唯一性,谨慎使用)

代码演示


    

结果演示

拓展

如果使用的是对象赋值,要使用ref属性而不是value属性


如果使用的只有一个参数的话,可以只写value属性


    

5、依赖注入

在官网的文档中有这么一句话: IOC is also known as dependency injection (DI) —> [ IOC 也称之为依赖注入 ]

两者的关系要看自己怎么理解,我的理解是IOC是创建一个对象放入到IOC容器中,用来实现主程序中被动的接收对象,遵从"开闭原则"(主要是创建对象和被IOC容器托管对象),而依赖注入讲解的基本上就是如何创建对象。所以我很是赞同狂神说的DI(依赖注入)是实现IOC的方法

实现依赖注入的几种方式

基于构造器的依赖注入基于setter方法的依赖注入

基于xxx实现的依赖注入,意味着如果类中没有这个构造器方法或者setter方法,就不能执行。

1、基于构造器的依赖注入

上面上一小节中讲述的就是这个

2、基于setter方法的依赖注入

给出官网文档中的一句话:

Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.

# 基于Setter的DI是在调用无参数构造函数或无参数静态工厂方法实例化bean之后,通过容器调用bean上的setter方法来完成的。

如何理解,我们在代码中去解释,现在要注意里面的两个点

调用无参数构造函数或无参数静态工厂方法通过容器调用bean上的setter方法来完成的

代码演示:

 



    
    
    
    

结果演示:

官方文档代码


    
    
    
    
    

测试环境搭建

package com.company.pojo;

import java.util.*;


public class Student {
    //测试基本数据类型依赖注入 type
    private String name;
    //测试引用类依赖注入 ref
    private Address address;
    //测试数组依赖注入
    private String[] books;
    //测试List集合依赖注入
    private List hobbys;
    //测试Map依赖注入
    private Map card;
    //测试set集合依赖注入
    private Set games;
    //测试空指针依赖注入
    private String wife;
    //测试配置类依赖注入
    private Properties info;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List getHobbys() {
        return hobbys;
    }

    public void setHobbys(List hobbys) {
        this.hobbys = hobbys;
    }

    public Map getCard() {
        return card;
    }

    public void setCard(Map card) {
        this.card = card;
    }

    public Set getGames() {
        return games;
    }

    public void setGames(Set games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hobbys=" + hobbys +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + ''' +
                ", info=" + info +
                '}';
    }
}

applicationContext.xml




    
        
     

    
        
        

        
        
        

        
        
            
                红楼梦
                西游记
                水浒传
                三国演义
            
        

        
        
            
                听歌
                敲代码
                看电影
            
        

        
        
            
                
                
            
        

        
        
            
                游戏1
                游戏2
                游戏3
            
        

        
        
            
        

        
        
            
                root
                123456
            
        
    

3、拓展

p 依赖注入

就是一种简洁的setter注入方式,这里贴官方的,比较好理解

这是setter注入


    
    
    
    
    

这是p依赖注入

注意 要导入p命名空间



    


c 依赖注入

则是对有参构造的依赖注入的简化版

还是与P命名空间一样的注意点,要导入C的命名空间



    
    

    
    
        
        
        
    

    
    


6、spring 容器配置

给出之前创建Spring IOC容器的代码

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

通过这个配置文件获取的IOC容器,所以我们对容器进行配置的话就是配置这个配置文件。

1、别名





调用的时候可以使用user,也可以使用user2

2、bean的配置

    

3、import

4、bean的作用域

六种作用域,重点掌握前面两种

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hg9hFmft-1647672738861)(G:/PrtSc/image-20210907151156075.png)]

单例模式:只有一个实例被创建,默认就是创建的单例模式




代码测试

import com.company.pojo.Student;
import com.company.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
    }

    @Test
    public void test()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
        User user = (User) context.getBean("user2");
        User user2 = context.getBean("user2", User.class);
        user.setAge(19);
        System.out.println(user);
        System.out.println(user2);
    }
}

测试结果:

null执行了无参构造函数
hello2执行了有参构造函数
User{name='hello2', age=19}
User{name='hello2', age=19}

结果分析:

1、首先创建了一个user2对象,执行了一次构造函数

2、是一个对象,一个对象字段的修改对另外一个对象字段造成了影响

原型模式: 每次创建都是一个新的实例




    

    
    
    

代码测试

import com.company.pojo.Student;
import com.company.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
    }

    @Test
    public void test()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
        User user = (User) context.getBean("user2");
        User user2 = context.getBean("user2", User.class);
        user.setAge(19);
        System.out.println(user);
        System.out.println(user2);
    }
}

测试结果:

null执行了无参构造函数
hello2执行了有参构造函数
hello2执行了有参构造函数
User{name='hello2', age=19}
User{name='hello2', age=18}

结果分析:

1、首先创建了两个user2对象,执行了两次构造函数

2、是两个对象,而不是一个对象,一个对象字段的修改对另外一个对象字段没有影响

其他的作用域,了解即可

7、Bean的自动装配

官方上称这种方式为Annotation-based Container Configuration 来配置bean的元数据

场景模拟

一个人养了一只宠物猫,一条宠物狗

Cat.java

package com.company.pojo;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
    private String name;

    public void shout() {
        System.out.println("喵喵喵~");
    }
}

Dog.java

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dog {
    private String name;

    public void shout() {
        System.out.println("汪汪汪~");
    }
}

People.java

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class People {
    private String name;
    private Dog dog;
    private Cat cat;
}	

ApplicationContext.xml




    
        
        
        
    

代码测试:

import com.company.pojo.Hello;
import com.company.pojo.People;
import com.company.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 获取Spring的上下文对象(同时也是IOC容器)
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        People people = context.getBean("people", People.class);

        people.getCat().shout();
        people.getDog().shout();
    }
}

结果演示:

byName 类型的 自动装配




    
    

    
    
    
    
        
    

byType 类型的 自动装配




    
    

    
    
    
    
    
        
    

使用注解的方式进行自动装配 @Autowired

People.java

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class People {
    private String name;
    @Autowired
    // @Autowired 会自动使用byName和byType这两种类型
    private Dog dog;
    @Autowired
    private Cat cat;
}

ApplicationContext.xml

切记 要开启注解支持以及导入Context的命名空间




   
    
    

    
    
    
    
    

    
        
    


@Autowired 使用注意

使用位置

在类的字段名上在类的set方法上 使用 @AutoWired 之后的改变

set方法可以不写

@Qualifier 注解

@Autowired 默认的装配模式的是byName,如果Spring容器中有多个相同类型且不同id的被引用的bean时,ByName方法和ByType都不能使用了,因为Spring容器不知道给引用其他bean的bean赋予什么值。这时候我们可以使用 @Qualifier 注解,指定属性指定的bean是什么,这时候就可以解决问题了

ApplicationContext.xml




    
    

    
    
    
    
    

    
        
    


People.java

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class People {
    private String name;
    @Autowired
    private Dog dog;
    @Autowired
    @Qualifier("cat1")
    // 指定Cat进行装配
    private Cat cat;
}

@Autowired 总结

@Autowired 自动装配的底层也是基于byName方式或者byType方式完成的,

默认是byName方法

如果byName方法弄不出来(没有保证byName的唯一性)就会使用byType方式

byName方式的优先级高于byType方式。

如果byName 和 byType都不能保证唯一性的话,就会报错

@Resource注解

上面的@Autowired是spring里面的,你只能在spring中使用,而这个@Resource 则是java里面的自带的注解。

1、使用@Resource 装配的开发步骤

导包



    javax.annotation
    javax.annotation-api
    1.3.2

2、装配方式与@Autowired 一致,就不加赘述了,首先byType,然后再是byName

3、@Resource 使用修改属性值来指定字段装配的是哪个bean

8、使用注解开发

官方上描述这种方式为Java-based Container Configuration,
配置bean的元数据方法之一

官方演示:

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

等同于


    

如果使用这种方式进行的配置,那么获取IOC容器的方法是

import com.company.config.MyConfig;
import com.company.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 这里我们是使用注解实现注入,而不是xml,故使用的类应该为注解配置上下文
        // 使用这个API AnnotationConfigApplcationContext
        // 然后使用这个不仅可以将@Configuration里面的注册到IOC容器中
        // 还可以注册@Component组件
        // 要想添加有三种实现方式
        // 第一种,全部作为 new AnnotationConfigApplicationContext的参数,这个参数类型是一个可变长参数
        // 第二种,使用实例化对象中的register方法
        // 第三种, 在@Configuration中添加@ComponentScan()注解
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        User user = (User) context.getBean("getUser");
        System.out.println(user);
    }
}

@Value 属性注入

可以直接在成员变量中注入,也可以在成员变量的set方法上注入,只能注入基本数据类型,引用数据类型要使用@AutoWired,其他复杂一点的map,list,properties最好使用xml进行注入。

这个属性注入注解只适用于简单的属性注入,复杂的的像map,list,properties等都不适用,最好使用xml进行注入,结构更加清晰

package com.company.pojo;

import org.junit.validator.ValidateWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


// 等价于 
// component 组件
@Component
public class User {

    // 
    @Value("user2")
    public String name;

    public String getName() {
        return name;
    }

    // 
    @Value("user2")
    public void setName(String name) {
        this.name = name;
    }

    public void User()
    {
        System.out.println("user被装配了");
    }
}

衍生注解

1、@Component的一些衍生注解

作用域

即bean是单例模式 还是 原型模式

// Scope 注解,标识bean是单例模式还是原型模式
@Scope("singleton")
public class User {

    // 
    @Value("user2")
    public String name;

    public void User()
    {
        System.out.println("user被装配了");
    }
}

拓展

1、@AutoWired 的 require属性

2、@Nullable 注解

9、Spring 实现 AOP 1、AOP概述

AOP : Aspect-oriented Programming (面向切面编程)

AOP将系统分为核心关注点和横切关注点两部分。核心关注点就是主业务流程,横切关注点就是提到的“方面”。

主业务流程归根到底是一个java方法,而且是对象的方法。在AOP中被称为被通知或被代理对象POJO。AOP的作用就是将核心关注点和横切关注点组合起来,术语叫做“增强”。最后实际用的是增强后的代理对象。

AOP中的一些概念

Aspect : 切面,是一个类,里面包含了要切入的方法。通常使用@Aspect注解的常规类或者适应常规类(基于模式的方法)来实现的。通常由PointCut 和 Advice方法组成。join point:方法执行的地方,比如在PointCut前 或者 在PointCut后执行Advice:通知,就是切面中的方法,也是通常在join point处执行的方法。Pointcut: 要切入方法的点

举个例子理解一下:以增删改查为例,不改变原有代码的逻辑往里面增加日志输出的功能

Aspect :将日志功能抽象成为了一个类,切面一般是一个类Advice : 日志功能PointCut : 要进行日志增强的位置join point :通常是PointCut 前后

Spring AOP 有如下增强

Before advice: 在PointCut的前面进行增强After returning advice: 在PointCut 的后面进行增强 (通常没有报异常)After throwing advice: 在抛出异常的地方进行增强After (finally) advice: 顾名思义,在异常返回的时候增强Around advice: 在PointCut的周围进行增强 2、实现AOP的几种方式

使用@AspectJ的方式实现AOP

首先,使用这个AOP织入功能,我们需要导入AspectJ的依赖包


    org.aspectj
    aspectjweaver
    1.9.7
    runtime

然后我们需要配置支持使用@AspectJ注解,两种方式

使用 java @Configuration 的方式

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

使用 xml 配置方式


定义一个Aspect 切面, 也和上面一样有两种方式

使用 xml 配置方式


    

使用 注解的方式

package org.xyz;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class NotVeryUsefulAspect {

}

但是这种方式注册的对象不会装配到IOC容器中,我们需要手动注入

使用@Component,然后在@Configuration 中使用@ComponentScan()在@Configuration 中使用 @Bean 的方式注册一个

定义PointCut 并使用注解的方式实现Join Cut

package com.company.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

// 使用注解实现AOP功能
// 这个不会自动注入到IOC容器中, 需要我们手动注入
@Aspect
public class AnnoAspect {

    @Before("execution(* com.company.service.UserServiceImpl.*(..))")
    public void beforeNote() {
        System.out.println("=============");
        System.out.println("在方法执行前输出");
    }

    @After("execution(* com.company.service.UserServiceImpl.*(..))")
    public void afterNote() {
        System.out.println("在方法执行后输出");
        System.out.println("=============");
    }
}

UserServiceImpl.java

package com.company.service;

public class UserServiceImpl {

    public void add() {
        System.out.println("插入操作");
    }

    public void remove() {
        System.out.println("移除操作");
    }

    public void update() {
        System.out.println("更新操作");
    }

    public void query() {
        System.out.println("查询操作");
    }
}

代码测试:

import com.company.config.Myconfig;
import com.company.pojo.Hello;
import com.company.pojo.People;
import com.company.pojo.User;
import com.company.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 获取Spring的上下文对象(同时也是IOC容器)
        ApplicationContext context =  new ClassPathXmlApplicationContext("applicationContext.xml");
        UserServiceImpl userService = context.getBean("userService", UserServiceImpl.class);

        userService.add();
        userService.query();
        userService.remove();
        userService.update();
    }
}

xml 配置






结果输出:

使用Spring的方式实现AOP

这里面会使用到xml配置,要使用xml配置,就要使用AOP的命名空间




有两个API接口 ,

AfterReturningAdvice 顾名思义,在要切入点方法后面进行切入MethodBeforeAdvice 顾名思义,在切入点方法前面进行切入

步骤实现

首先创建两个实现了上面那两个接口的类创建这两个类的bean对象实现AOP配置

实现配置代码



    
    

    
    
    
    

自定义类来实现AOP(使用切面 )

要了解切面的含义,切面就是横切关注点被模块化的类,就是有一个类,这个类里面包含了所有你要添加的功能。

由于自己写的普通方法没有上面那两个接口的功能(在切入点前后进行插入),而且我们把方法写进了一个类里面,故这次要配置的是切面,大同小异,无非要自己再配置切面里面的内容

自定义类

package com.company.diy;

public class DiyPointCut {

    public void before()
    {
        System.out.println("========方法执行前========");
    }

    public void after()
    {
        System.out.println("========方法执行后========");
    }
}

配置切面

那么怎么判断是before 方法呢?哪个是after方法呢? 简单,进行绑定不就好了


    
        
        

        
        
        
    

N、小结

不是总结,就提出一些要区分开来的知识点

IOC 配置元数据的几种方式

1、使用xml配置元数据



2、使用注解配置元数据

自动装配里面使用的到的注释@Resource,@Autowired,@Qualifier

注意 : 注释注入在XML注入之前执行。因此,XML配置覆盖了通过这两种方法连接的属性的注释。

@Required

位置:放在Setter方法上,

功能:标明这个属性必须填充,如果未填充,则会引发异常

@Autowired

位置:放在setter方法上以及引用属性上

功能:实现自动填充

@Primary

位置:放在setter属性上,

功能:@Autowired带来的可能有多个候选值的情况下,优先使用有@Primary注解标识的bean实例

@Qualifier

位置:放在setter属性上

功能:@Autowired带来的可能有多个候选值的情况下,优先使用有@Qualifier注解指定的bean实例

@Resource

位置:放在setter属性上或者字段上

功能:

3、使用java配置元数据

@Configuration@Bean@import

4、总结
这几种方法都是可以配置bean的元数据,也只会做这一件事情,不会将bean注入到IOC容器中,要注入到IOC容器中需要另外的配置。比如,编写xml的时候,intellij idea 会要我们绑定IOC容器,没有就创建。而像自动注入,和使用java_base Configuration 都需要自己Register到IOC容器中,或者使用@Component 和 @ComponentScan注解。

学习方式

没有基础的建议首先去找些视频观看,做项目,达到基本上能用这个框架了(虽然有些地方不知道为什么要这么弄没关系)。

复习的时候根据官网,复习自己之前记录的笔记,在官网上找到对应的知识,然后看下相关解释,为什么这么用,还能怎么用?

可能阅读的过程有些难受(一般都是英文的),但是也要耐下心来,耐住性子。慢慢看不急,有收获就行。建议在电脑上下载一个网易有道词典(可以小窗查词,划词查词),因为网页翻译整篇文章有些术语可能是直译中文,反倒妨碍阅读

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/773608.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号