spring创建对象的范围,生命周期,依赖注入注解方式的IOC和DI

1.spring创建对象的范围

1.1关于单例和多例的介绍

单例: 内存中只有一个对象,每次获取到该对象的地址值一样.

多例:内存中的每个对象都是一个新的对象,他们的地址值都不同.

spring默认的情况下创建的对象都是单例的. (每次返回的对象都是同一个)
默认scope=singleton

1.1.1单例代码结果演示

代码

  
    

结果

spring创建对象的范围,生命周期,依赖注入注解方式的IOC和DI_第1张图片

1.1.2多例代码结果演示

代码

  
    

结果

spring创建对象的范围,生命周期,依赖注入注解方式的IOC和DI_第2张图片

1.3spring创建对象的生命周期

spring创建的对象什么时候创建

回答:配置文件读取加载的时候对象就创建(scope=“singleton”)

spring读取xml文件的时候,不会创建对象
在调用容器的getBean(“id”) 得到对象(scope=“prototype”)


spring创建的对象什么时候运行

回答:当使用该对象的时候就运行


spring创建的对象什么时候销毁

回答:当spring的容器关闭的时候对象销毁

!!注意

//对Spring的生命周期进行测试
@Test
public void test05(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
            "applicationContext.xml"
    );
    Student student = context.getBean("student", Student.class);
    student.service();
    //猜测结果,init方法应该这service方法执行前执行
    context.close();
    //这里不报错,因为student2还存在堆内存
     student2.service();
	//这里报错,因为spring容器已经销毁
    Student student1 = context.getBean("student", Student.class);
    //猜测destroy方法应该在这句话执行后结束并且service不会再执行
    student3.service();
}

二.依赖注入

1.概念

DI (dependency injection) 依赖注入

含义:就是给对象的属性设置值.

原来给对象的属性设置值: set方法给对象设置值 构造方法给对象初始化的时候设置值.

1.1set方式设置属性

注意点:

  1. set注入 ,必须要有set方法
  2. personbean.xml
    这里不写的属性为0/Null




    

    
    
        
        
        
        
        
    

  1. 测试
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PersonTest {

    /*
      1.创建对象给对象设置属性,打印的对象是有属性的,属性是在xml中设置的.
      2.执行过程中会调用set方法,打断点查看流程
      3.是否根据set方法来设置的: 修改set方法
     */
    @Test
    public void testPerson(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("personbean.xml");
        Person person = context.getBean("person", Person.class);
        System.out.println(person);
    }
}

1.2构造方式注入

  1. 前提条件类中必须有有参构造方法
  2. personbean.xml
    这里必须写全有参构造中出现的属性,不然报编译时错误
 
    
        
        
        
        
        
    

1.3p名称空间注入和c名称空间注入

  1. P代表propertory 属性, 是set注入的简化方式 (提供set方法)

  2. C代表Constructor 构造注入的简化方式 (提供构造方法)

  3. 配置文件
    先引入
    xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
    这里的c -Constructor 构造注入的简化方式属性必须全写,不然报运行时错误




 
    
    

    
    


科普

①编译错误一般指语法错误或者很明显的逻辑错误。
如:缺少分号,少写括号,关键字书写错误等, 在eclipse往往会画红线。
②运行错误是在没有编译错误的基础上运行后产生的逻辑错误。
如:空指针异常,除数为0,越界访问等,一般会抛出异常。

1.4复杂数据类型注入

类中属性Aarry 数组 List 集合 Map集合 Set集合 Properties集合属性设置值.

  1. ComplexBean

import java.util.*;

/**
 * 采用的是set方式注入
 */
public class ComplexBean {
    private String[] arr;
    private List list;
    private Set set;
    private Map map;
    private Properties properties;

    public String[] getArr() {
        return arr;
    }

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    public List getList() {
        return list;
    }

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

    public Set getSet() {
        return set;
    }

    public void setSet(Set set) {
        this.set = set;
    }

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "ComplexBean{" +
                "arr=" + Arrays.toString(arr) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}
  1. 配置文件

    
        
        
            
                柯镇恶
                郭靖
                杨过
            
        
        
        
            
               
                
                
            
        

        
        
            
                乔峰
                段誉
                虚竹
            
        

        
        
            
                
                
                
            
        

        
        
            
                石破天
                虚竹
                张无忌
            
        
    
  1. 测试
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.*;

public class ComplexBeanTest {

    @Test
    public void testComplexBean(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("personbean.xml");
        ComplexBean complexBean = context.getBean("complexBean", ComplexBean.class);
        String[] arr = complexBean.getArr();
        System.out.println(Arrays.toString(arr));
        System.out.println("---------------------");
        List list = complexBean.getList();
        for (Person person : list) {
            System.out.println(person);
        }

        System.out.println("---------------------");
        Set set = complexBean.getSet();
        System.out.println(set);
        System.out.println("---------------------");

        Map map = complexBean.getMap();
        Set> entrySet = map.entrySet();
        for (Map.Entry entry : entrySet) {
            System.out.println(entry.getKey()+ " "+ entry.getValue());
        }
        System.out.println("---------------------");
        Properties properties = complexBean.getProperties();
        System.out.println(properties);

    }
}

三.注解方式的IOC和DI

1.使用注解方式创建对象

1.需要导入一个aop.jar的jar ,该包已经被spring-context.jar依赖引入了.不需要再导入(Idea)

2.在配置文件中需要进行一个包扫描的配置

2.代码实现

  1. annotationbean.xml



    
    

  1. UserService接口
public interface UserService {

    //查询用户
    public void  findUsers();
}
  1. UserServiceImpl
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

//@Component注解 ===>  

// @Component    默认的id是类名首字母小写
//@Component("abc")  //手动的指定了  

/**
 * 和Component注解作用一样的还有其他3个:
 * 这4个注解的作用一样
 */

//@Component   //不确定是那一层使用Component
//@Controller  //确定是表现层/控制层 使用Controller
@Service     //如果是业务逻辑使用 Service
//@Repository  // 如果是dao持久层   Repository
public class UserServiceImpl implements UserService {

    public void findUsers() {
        System.out.println("用户查询完毕");
    }
}

2.使用注解方式注入

  1. UserDao接口
public interface UserDao {

    public void  queryUsers();
}
  1. UserDaoImpl

@Repository("son1")
public class UserDaoImpl implements UserDao {
    public void queryUsers() {
        System.out.println("1111   dao的查询user方法");
    }
}
  1. UserDaoImpl02
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

//@Component注解 ===>  

// @Component    默认的id是类名首字母小写
//@Component("abc")  //手动的指定了  

/**
 * 和Component注解作用一样的还有其他3个:
 * 这4个注解的作用一样
 */

//@Component   //不确定是那一层使用Component
//@Controller  //确定是表现层/控制层 使用Controller
@Service     //如果是业务逻辑使用 Service
//@Repository  // 如果是dao持久层   Repository
public class UserServiceImpl implements UserService {

    //使用自动注入的注解,将userDao的实现类UserDaoImpl注入进来
    //byType按照类型注入 ,问题如果UserDao中有多个实现类,注入的是哪个? 会报错
    @Autowired
    @Qualifier("son2")  //根据的bean id值来指定
    private UserDao userDao;

    public void findUsers() {
        System.out.println("Service用户查询完毕");
        //创建dao的对象并调用dao的query方法
        userDao.queryUsers();
    }
}
  1. 测试
public class UserServiceTest {
    @Test
    public void testUserService(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("annotationbean.xml");
        UserServiceImpl userServiceImpl = context.getBean("userServiceImpl", UserServiceImpl.class);
        userServiceImpl.findUsers();

    }
}

3.其他的注入方式

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.annotation.Resources;


@Service     //如果是业务逻辑使用 Service
public class UserServiceImpl implements UserService {

    //方式2注入:
    //@Value("#{son1}")  //将UserDaoImpl02注入进来
    //private UserDao userDao;

    @Value("志平")
    private String name;

    //注入方式3:jdk的注入
   @Resource(name="son1")
    private UserDao userDao;

    public void findUsers() {
        System.out.println("Service用户查询完毕" +name);
        //创建dao的对象并调用dao的query方法
        userDao.queryUsers();
    }
}

你可能感兴趣的:(java,Spring)