您当前的位置: 首页 >  容器

星夜孤帆

暂无认证

  • 2浏览

    0关注

    626博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Spring IOC容器

星夜孤帆 发布时间:2020-11-20 20:30:26 ,浏览量:2

一、Spring框架概述 1.1 概述

1.Spring是轻量级的开源JavaEE框架

2.Spring可以解决企业应用开发的复杂性

3.Spring有两个核心部分:IOC和AOP

  • IOC: 控制反转,把创建对象过程交给Spring进行管理。
  • Aop:面向切面编程,不修改源代码的情况下,进行功能增强。

4.Spring特点

  • 方便解耦,简化开发
  • Aop编程支持
  • 方便程序测试
  • 方便和其他框架进行整合
  • 方便进行事务操作
  • 降低API开发难度
1.2 入门案例 1.2.1 创建类User

创建普通类,在这个类创建普通方法

public class User {
    public void add() {
        System.out.println("创建对象");
    }
}
 1.2.2 普通方式创建User对象
    @Test
    public void testAdd1() {
        User user = new User();
        user.add();
    }
 1.2.3 使用Spring创建对象

resources目录下创建xml




       
    

进行测试代码编写 

public class TestDemo {

    @Test
    public void testAdd() {
        //1 加载spring配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

        //2 获取配置创建的对象
        User user = context.getBean("user", User.class);

        System.out.println(user);

        user.add();
    }

    @Test
    public void testAdd1() {
        User user = new User();
        user.add();
    }
}

二、IOC 2.1 什么是IOC
  1. 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
  2. 使用IOC目的:为了降低耦合度
  3. 做入门案例就是IOC实现
2.2 IOC底层原理

xml解析、工厂模式、反射

2.2.1 创建对象原始过程

原始方式,直接通过new的方式创建

2.2.2 工厂模式创建对象

通过工厂模式,创建对象

2.2.3 IOC容器创建过程

2.3 IOC(BeanFactory接口)

1、IOC思想基于IOC容器完成,IOC容器底层就是对象工厂

2、Spring提供IOC容器实现两种方式:(两个接口) (1)BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用* 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象 (2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用* 加载配置文件时候就会把在配置文件对象进行创建

3、ApplicationContext接口有实现类

三、IOC操作Bean管理 3.1 什么是Bean管理

Bean管理指的是两个操作

  1. Spring创建对象
  2. Spring注入属性

Bean管理操作有两种方式

  1. 基于xml配置文件方式实现
  2. 基于注解方式实现
3.2 IOC操作Bean管理(基于xml方式) 3.2.1. 基于xml方式创建对象
    
    

1.在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建

2.在bean标签有很多属性,介绍常用的属性

  • id属性:唯一标识
  • class属性:类全路径(包类路径)

3.创建对象时候,默认也是执行无参数构造方法完成对象创建,如果没有无参构造方法报错- No default constructor found; nested exception is java.lang.NoSuchMethodException: com.best.spring.module.User.()

3.2.2 基于xml方式注入属性

DI:依赖注入,就是注入属性

1.原始的注入方式

public class Book {

    private String bname;

    //set方法注入
    public void setBname(String bname) {
        this.bname = bname;
    }

    //有参数构造注入
    public Book(String bname) {
        this.bname = bname;
    }

    public static void main(String[] args) {
        Book book = new Book("构造器注入");
        book.setBname("set注入");
    }

}

2. 第一种注入方式:使用set方法进行注入

(1).创建类,定义属性和对应的set方法

/**
 * 演示使用set方法进行注入属性
 */
public class Book {

    //创建属性
    private String bname;
    private String bauthor;

    //创建属性对应的set方法
    public void setBname(String bname) {
        this.bname = bname;
    }

    public void setBauthor(String bauthor) {
        this.bauthor = bauthor;
    }

    public void testDemo() {
        System.out.println(bname + "::" + bauthor);
    }

}

(2) 在spring配置文件配置对象创建,配置属性注入

    
    
    
        
        
    

(3) 测试

    @Test
    public void testBook1() {
        //1 加载spring配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

        //2 获取配置创建的对象
        Book book = context.getBean("book", Book.class);

        System.out.println(book);

        book.testDemo();
    }

3. 第二种注入方式:使用有参数构造进行注入

(1) 创建类,定义属性,创建属性对应有参数构造方法

/**
 * 使用有参数构造注入
 */
public class Orders {
    //属性
    private String oname;
    private String address;
    //有参数构造
    public Orders(String oname, String address) {
        this.oname = oname;
        this.address = address;
    }
}

(2) 在spring配置文件中进行配置

    
    
        
        
    

4. p名称空间注入

(1) 使用p名称空间注入,可以简化基于xml配置方式

第一步 添加p名称空间在配置文件中


第二步 进行属性注入,在bean标签里面进行操作

 
3.2.3 xm注入其他类型属性

1. 字面量

(1) null值

   

(2) 属性值包含特殊符号



    >]]>

2.注入属性-外部bean

(1) 创建两个类service类和dao类

(2) 在service调用dao里面的方法

(3) 在spring配置文件中进行配置

public class UserService {

    //创建UserDao类型属性,生成set方法
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add() {
        System.out.println("service add .....");

        //原始方式: 创建UserDao对象
        UserDao userDao = new UserDaoImpl();
        userDao.update();
    }
}




    
    
        
        
    
    

3. 注入属性-内部bean

(1) 一对多关系: 部门和员工

一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多

(2) 在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示

//部门类
public class Dept {
    private String dname;
    public void setDname(String dname) {
        this.dname = dname;
    }
}
//员工类
public class Emp {

    private String ename;
    private String gender;
    //员工属于某一个部门,使用对象形式表示
    private Dept dept;

    public void setEname(String ename) {
        this.ename = ename;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}



    
    
        
        
        
        
        
            
                
            
        
    

 4. 注入属性-级联赋值

(1) 第一种写法




    
    
        
        
        
        
        
    
    
        
    

(2) 第二种写法

    //生成dept的get方法
    public Dept getDept() {
        return dept;
    }
    
    
        
        
        
        
        
        
    
    
        
    
3.2.4 xm注入集合属性

1. 注入数组类型属性

2. 注入List集合类型属性

3. 注入Map集合类型属性

(1) 创建类,定义数组、list、map、set类型属性,生成对应set方法

public class Stu {

    //1 数组类型属性
    private String[] courses;

    //2 list集合类型属性
    private List list;

    //3 map集合类型属性
    private Map maps;

    //4 set集合类型属性
    private Set sets;

    public void setSets(Set sets) {
        this.sets = sets;
    }

    public void setCourses(String[] courses) {
        this.courses = courses;
    }

    public void setList(List list) {
        this.list = list;
    }

    public void setMaps(Map maps) {
        this.maps = maps;
    }
}

(2) 在spring配置文件进行配置

    
    
        
        
            
                java课程
                数据库课程
            
        
        
        
            
                张三
                李四
            
        
        
        
            
                
                
            
        
        
        
            
                mysql
                redis
            
        
    

4. 在集合里面设置对象类型值

//课程类
public class Course {
    private String cname; //课程名称
    public void setCname(String cname) {
        this.cname = cname;
    }
}
    //学生所学多门课程
    private List courseList;
    public void setCourseList(List courseList) {
        this.courseList = courseList;
    }
    
    
        
    
    
        
    
        
        
            
                
                
            
        

5. 把集合注入部分提取出来

(1) 在spring配置文件中引入名称空间util


(2) 使用util标签完成list集合注入提取

    
    
        易筋经
        九阴真经
        九阳神功
    

    
    
        
    
3.2.5 FactoryBean

1. Spring有两种类型bean,一种普通bean,另外一种工厂bean(FactoryBean)

2. 普通bean:在配置文件中定义bean类型就是返回类型

3. 工厂bean:在配置文件定义bean类型可以和返回类型不一样

第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean

第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型

    
    
public class MyBean implements FactoryBean {

    //定义返回bean
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("abc");
        return course;
    }

    @Override
    public Class getObjectType() {
        return null;
    }
}
   @Test
    public void test3() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean8.xml");
        //实际返回的是Course
        Course course = context.getBean("myBean", Course.class);
        System.out.println(course);
    }
3.2.6 bean的作用域

1. 在Spring里面,设置创建bean实例是单实例还是多实例

2. 在Spring里面,默认情况下,bean是单实例对象

3. 如何设置单实例还是多实例

(1) 在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例

(2) scope属性值

第一个值 默认值,singleton,表示是单实例对象

第二个值 prototype,表示是多实例对象

    
    
        
        
        

        
        
            >]]>
        
    

(3) singleton和prototype区别

第一 singleton单实例,prototype多实例

第二 设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象

设置scope值是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象

3.2.7 bean生命周期

1. 生命周期

从对象创建到对象销毁的过程

2. bean生命周期

  1. 通过构造器创建bean实例(无参数构造)
  2. 为bean的属性设置值和对其他bean的引用(调用set方法)
  3. 调用bean的初始化方法(需要配置初始化方法)
  4. bean可以使用了(获取到bean的实例)
  5. 当容器关闭时,调用bean的销毁方法(需要配置销毁的方法)

3. 演示bean生命周期

public class Orders {

    private String oname;

    //无参数构造

    public Orders() {
        System.out.println("第一步 执行无参数构造创建bean实例");
    }

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第二步 调用set方法设置属性值");
    }

    //创建执行的初始化的方法
    public void initMethod() {
        System.out.println("第三步 执行初始化的方法");
    }

    //创建执行的销毁的方法
    public void destroyMethod() {
        System.out.println("第五步 执行销毁的方法");
    }
}
    
        
    
    @Test
    public void testBean() {
//        ApplicationContext context = new ClassPathXmlApplicationContext("bean9.xml");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean9.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第四步 获取创建bean实例对象");
        System.out.println(orders);
        context.close();
    }

 

4. bean的后置处理器,bean生命周期有七步

  1. 通过构造器创建bean实例(无参数构造)
  2. 为bean的属性设置值和对其他bean的引用(调用set方法)
  3. 把bean实例传递bean后置处理器的方法postProcessBeforeInitialization
  4. 调用bean的初始化方法(需要配置初始化方法)
  5. 把bean实例传递bean后置处理器的方法postProcessAfterInitialization
  6. bean可以使用了(获取到bean的实例)
  7. 当容器关闭时,调用bean的销毁方法(需要配置销毁的方法)

5. 演示添加后置处理器效果

(1) 创建类,实现接口BeanPostProcessor,创建后置处理器

public class MyBeanPost implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行的方法");
        return bean;
    }
}



    
        
    

    
    

 

3.2.8 xml自动装配

1. 什么是自动装配

根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入

2. 演示自动装配过程

(1) 根据属性名称自动注入

    
    

    
    

(2) 根据属性类型自动注入

    
    

    
    
 3.2.9 外部属性文件

1. 直接配置数据库信息

(1) 配置德鲁伊连接池

(2) 引入德鲁伊连接池依赖jar包

    
    
        
        
        
        
    

 2. 引入外部属性文件配置数据库连接池

(1) 创建外部属性文件,properties格式文件,写数据库信息

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=root

(2) 把外部properties属性文件引入到spring配置文件中

引入context名称空间


在spring配置文件使用标签引入外部属性文件

    
    

    
    
        
        
        
        
    
3.3 IOC操作Bean管理(基于注解方式) 3.3.1 什么是注解
  1. 注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值..)
  2. 使用注解,注解作用在类上面,方法上面,属性上面
  3. 使用注解目的: 简化xml配置
3.3.2 Spring针对Bean管理中创建对象提供注解

@Component

@Service

@Controller

@Repository

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

3.3.3 基于注解方式实现对象创建

第一步 引入依赖

第二步 开启组件扫描




    
    

第三步 创建类,在类上面添加创建对象注解

/**
 * 在注解里面value属性值可以省略不写
 * 默认值是类名称,首字母小写
 * UserService --userService
 */

@Component(value = "userService1") //创建对象,等价于
public class UserService1 {

    public void add() {
        System.out.println("service add....");
    }
}
3.3.4 开启组件扫描细节配置



    
    

    
    
        
    

    
    
        
    
3.3.5 基于注解方式实现属性注入

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

第一步 把service和dao对象创建,在service和到类添加创建对象注解

@Repository
public class StudentDaoImpl implements StudentDao {
    @Override
    public void add() {
        System.out.println("dao add .....");
    }
}

第二步 在service注入dao对象,在service类添加dao类型属性,在属性上面使用注解

@Service
public class StudentService {

    //定义dao类型属性
    //不需要添加set方法
    //添加注入属性注解
    @Autowired  //根据类型进行注入
    private StudentDao studentDao;

    public void add() {
        System.out.println("service add ....");
        studentDao.add();
    }
}

2. @Qualifier:根据名称进行注入

这个@Qualifier注解的使用,和上面@Autowired一起使用

@Repository(value = "studentDaoImpl1")
public class StudentDaoImpl implements StudentDao {
    @Override
    public void add() {
        System.out.println("dao add .....");
    }
}
@Service
public class StudentService {

    //定义dao类型属性
    //不需要添加set方法
    //添加注入属性注解
    @Autowired  //根据名称进行注入
    @Qualifier(value = "studentDaoImpl1")
    private StudentDao studentDao;

    public void add() {
        System.out.println("service add ....");
        studentDao.add();
    }
}

3.@Resources:可以根据类型注入,可以根据名称注入

@Service
public class StudentService {

    //定义dao类型属性
    //不需要添加set方法
    //添加注入属性注解
//    @Autowired  //根据名称进行注入
//    @Qualifier(value = "studentDaoImpl1")

    //@Resource //根据类型进行注入
    @Resource(name = "studentDaoImpl1") //根据名称进行注入
    private StudentDao studentDao;

    public void add() {
        System.out.println("service add ....");
        studentDao.add();
    }
}

4. @Value:注入普通类型属性

    @Value(value = "abc")
    private String name;
3.3.6 完全注解开发

1. 创建配置类,替代xml配置文件

@Configuration //作为配置类,替代xml配置文件
@ComponentScan(basePackages = {"com.best"})
public class SpringConfig {
}

2.编写测试类

    @Test
    public void testService2() {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        StudentService studentService = context.getBean("studentService", StudentService.class);
        System.out.println(studentService);
        studentService.add();
    }

源码,spring面试题,spirng教程,学习笔记

关注
打赏
1636984416
查看更多评论
立即登录/注册

微信扫码登录

0.3027s