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

Spring学习---IOC

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

Spring学习---IOC

Spring学习

IOC---控制反转(反转控制)

IOC是Java把创建和调用对象的工作交给Spring容器来进行处理,目的是为了降低耦合度

底层

底层有三部分xml文件解析、工厂模式、反射( 获取Java的字节码文件【即Java编译后的 .class文件】,得到其中的方法和变量进行调用 )

工厂模式---就是建立一个类做工厂,然后将想要创建的类的对象都在里面实现使用只要调用这个工厂类的方法就行了,但是耦合度还是很高

IOC过程

1、创建xml配置文件,在配置文件时将想要创建、调用的类都装进去

2、创建一个工厂类,在里面解析xml文件,通过反射创建对象,得到文件的编码文件

String classValue = 解析配置文件
Class cls = Class.forName(classValue)

3、创建类的实例对象并返回该值

 
return (类型转换)cls.newInstance();

IOC思想和功能实现接口

IOC思想基于IOC容器,IOC底层实际就是对象工厂

IOC提供了两个接口用来实现IOC容器

1)BeanFactory,是Spring自带的接口,他只会在类需要被用到时才会创建对象,不然就不会创建对象,不推荐在开发时使用

2)ApplicationContext,BeanFactory的子接口是一个功能更加强大的接口,也能够解析获取xml文件中的类,并创建对象不管需不需要调用。平时开发时使用,因为Spring经常会跟Web项目一起进行工作,需要在服务器启动时就完成各项消耗资源的工作

3)ApplicationFactory接口有两个实现类ClassPathXmlApplicationContext和FileSystemXmlApplicationContext

ClassPathXmlApplicationContext实现类解析xml文件是在src目录下需要使用时

FileSystemXmlApplicationContext实现类使用时需要写上xml文件在磁盘上的准确目录:D:hihello...

Bean管理操作有两种方式

1)基于xml文件管理

2)基于注解管理

IOC管理xml方式创建对象和注入属性

<1>配置对象创建

    
   

通过bean标签添加对应的属性值是实现对象的创建,bean中有两个属性值需要注意id 和 name

id是具有唯一性,用于区别创建的对象,里面的值不能添加符号别的。

name可以在里面添加特殊符号,这个属性本来是提供给status1使用的,但是因为技术原因不再使用这个技术

class属性是用来指明想要创建对象的类,类全路径

在创建对象时通过调用无参构造方法创建类的对象,当创建了有参构造方法后,也要创建无参构造方法

A <2>注入属性 DI(依赖注入、属性注入) set方法

创建类和方法、变量

public class ToBean {
    public String name;
    public String author;

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

    public void setAuthor(String author) {
        this.author = author;
    }

    public void store(){
        System.out.println(name+"--"+author);
    }
}
 

在xml文件 中使用bean标签实现对象创建

其中注入属性就是字在bean标签对中通过property标签进行注入属性

在property边里有name 、value属性对应起来进行注入属性

 
        
        
    

<3>解析xml文件

   
 @Test
    public void toBean(){
        //解析xml文件
        ApplicationContext application = new ClassPathXmlApplicationContext("hi.xml");
        
       //获取对象
        ToBean toBean = application.getBean("toBean", ToBean.class);
        toBean.store();
    }

<4>获取想要调用的类对象

<5>使用对象

P 名称空间(实际使用名称空间实现) 注入

1、首先对xml文件beans标签中的内容进行修改,添加 xmls:p 实现添加名称空间

 

2、使用

    

在bean标签中使用 p名称空间,输入后就能发现可以对class指向的类中的变量进行赋值(属性注入),这个方法适用于set方法注入属性(简化代码)

B 注入属性 DI 有参构造方法

 
        
        
    

在通过有参构造方法进行实现属性注入时,使用constructor-arg标签实现,跟property差不多

其中也有index、value通过索引参数实现属性注入

调用一样

   
 @Test
    public void toBean(){
        ApplicationContext application = new ClassPathXmlApplicationContext("hi.xml");
        ToBean toBean = application.getBean("toBean", ToBean.class);
        toBean.store();
    }

IOC操作Bean,xml注入其他类型属性

字面量:就是在类中定义的变量被直接赋值,或者在xml文件中对通过属性注入(name=value)方式赋值,设置使用固定值就是字面量。

设置null值


        
        
            
        
    

设置特殊符号使用转义符或CDATA

标签中的所有内容都是值


    
    
        
        
        
    

IOC管理---外部Bean

外部Bean注入就是在实际开发中,会分很多层,上层调用下层方法时要通过实例化对象实现,而现在来说就是通过外部Bean注入。

在AddUser中

public class AddUser {
//    将类对象做为类内部属性,通过set方法实现属性注入
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void addUser(){
        userDao.addUser();
    }
}

在xml文件里

首先创建上层类(AddUser)对象,由于使用了set方法进行属性注入,所以采用property标签以name=ref的方式进行注入,因为类中的属性是一个类对象,所以不能用value,要用ref

其次要注意的是创建UerDao的对象,由于并没有在service层中的类AddUser中实例化它,在使用中要使用到他的方法,创建它的对象时,使用bean标签,class要指向它的实现类,id值与 注入的属性值(ref)一致

 

//   创建属性的对象时,属性的id值与注入属性的值(ref)一致
    

    
        
    

这就叫外部Bean注入

IOC管理---内部Bean和级联赋值

内部bean的属性注入

bean类中

里面有另一个类( Student )作为内部属性



public class Student {
    private String stuName;
    private String hobby;
    private School school;

    public void setSchool(School school) {
        this.school = school;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }
    }

xml文件中

在xml文件中对bean类进行属性注入,由于student中有一个类对象做属性,所以就可以在属性注入时采取 内部bean注入,即在property标签中嵌套标签,再在bean标签中嵌套标签实现属性注入。这就叫 内部bean注入



 
        
        
        
            
                
            
        
     

第二种 外部bean注入

外部注入就是在进行注入属性时,使用property标签以name=ref进行注入,将对象类中的实体对象属性在外面重新用bean标签创建对象并用property注入属性,再用ref获取创建对象的id实现属性注入

这里注意 ref的值是要等与外部bean创建对象的id值,不是id值等于ref值




    
    
    


    

第三种 级联赋值

级联赋值是在外面创建bean对象,在内部通过property标签以name=value的方式进行属性注入,用 .运算符取到内部实体类属性的属性并赋值

这种 外部bean属性注入要注意,该对象的类中要有这个实体类属性的get方法,在进行属性注入 之前要先以name=ref给内部实体类属性进行属性注入。并且,我发现对同一个属性进行注入,这种方式的优先级大于外部bean标签内注入属性



    
        
        
        
        
    
    
        
     

IOC管理---对集合类型的属性进行属性注入

在bean类中



public class Collection {
    private String[] arrayList;
    private List list;
    private Map map;
    private Set set;

    public void setArrayList(String[] arrayList) {
        this.arrayList = arrayList;
    }

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

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

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

    @Override
    public String toString() {
        return "Collection{" +
                "arrayList=" + Arrays.toString(arrayList) +
                ", list=" + list +
                ", map=" + map +
                ", set=" + set +
                '}';
    }
}

在xml文件中

在对集合类属性进行属性注入时,在property标签中使用对应类型的标签对,在标签对内部通过value标签对list进行属性注入多个值。当然还是一个属性一个property标签

注意:map属性进行属性注入时使用entry标签,并在标签里面通过key=value的方式注入,通过多个entry标签实现注入多个值




    
        
            心态
            身体
            学习
        
    
    
        
            快乐
            健康
            循序渐进
        
    
    
        
            
            
            
        
    
    
        
            good
            god
            gd
        
    

当集合类型中的参数是对象类型时




      
          
          
          
      
    


    


    

在注入属性时使用property标签以name->list->ref进行注入,这样就能注入多个对象,ref标签里面通过bean指定要注入的类对象

提取list属性注入公共代码

在bean中



public class Course {
    private List list;

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

    @Override
    public String toString() {
        return "Course{" +
                "list=" + list +
                '}';
    }
}

在xml文件中

做公共代码块时需要先添加名称空间util,对beans标签里面的内容做修改如下



然后通过调用命名空间标签uil:list做出公共list注入代码,设置一个id,在有对象需要进行list类型属性注入时就可以通过ref属性引用公共代码块

可以发现ref负责引入对象类属性的,list属性注入 公共代码块也是一个对象,有自己的id




    1
    2
    3
    4



    

这样的提取集合类型的属性注入公共代码块可以同样应用于map和set集合

IOC管理---FactoryBean

普通bean--在获取它的对象时返回的跟定义时的对象一样

FactoryBean--在获取对象时返回的值可以跟定义的时的值不一样。用过实现FactoryBean这个接口实现

在xml文件中

定义的bean是testbean



在TestBean中

通过FactoryBean后的参数指定返回的bean类型,通过getObject方法实现对返回bean对象的操作



public class TestBean implements FactoryBean {
    @Override
    public School getObject() throws Exception {
        School school = new School();
        school.setName("哈哈大笑");
        return school;
    }

    @Override
    public Class getObjectType() {
        return null;
    }
}

IOC管理---单实例和多实例(Bean的作用域)

单实例---默认情况下创建bean对象是单实例,在调用这个bean对象时不管调用几个都会得到一样的bean对象

多实例---使用bean标签中的属性scope,设置值为prototype,在调用这个bean对象时会得到不同的bean对象

在xml文件中

 

在使用多实例时,不在解析xml文件时创建对象,而是在使用geBean方法时创建对象,实现创建多个不同对象

此外scope属性还有request和session两个属性,request是在一次请求中创建的对象,会把bean对象放进请求中

session是会将创建的bean对象放进一次会话中

IOC管理---bean的生命周期

bean会经历bean对象的创建( 通过set方法注入属性 )、bean的初始化方法之前、bean的初始化方法、bean的初始化方法后、bean对象的获取、bean对象的销毁( 销毁方法要将解析xml文件的对象转换为ClassPathXmlApplicationContext类型调用close方法实现销毁 )

在xml文件中

文件中配置了一个类prosess类用来做初始化前后的方法的实现

在想要使用初始化和销毁后的功能时,要自己声明bean中的哪一个类是初始化方法,哪一个类是销毁方法。用来实现对应功能

当在一个xml文件中添加了后置前置处理器会给当前文件中的所有bean都添加后置前置处理器




在prosess文件中

实现BeanPostProcess接口,调用了里面的初始化前置方法和初始化后置方法



public class Prosess 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;
    }
}

IOC管理---自动装配

自动装配就是不用手动注入,通过autowire属性的两个值( byName、byType ),实现自动匹配注入

在xml文件中





IOC管理---引入配置文件

在xml文件中

使用时要导入包,记住DruidDataSource类的路径在pool包下




    
    

    
        
        
        
        
    

在properties文件中

把该加的都加上,在key命名时最好加个前缀,便于区分和避免出错



druid.DriverClassname=com.mysql.cj.jdbc.Driver
druid.url=jdbc:mysql://localhost:3308/book?characterEncoding=utf8&useSSL=true&serverTimezone=UTC
druid.username=root
druid.password=123456

IOC管理---基于注解方式实现创建对象和属性注入

首先引入依赖【spring-aop-5.2.9.RELEASE.jar】

注解就是java代码中有特殊意义的符号,目的是为了简化xml配置文件的配置

创建对象的注解:【@Component】、【@Service】、【@Cotroller】、【@Repository】。功能一样,用哪个都行在那用都可以,但是建议在service层中用@Service,在Web层用@Cotroller,在持久层用@Repository

注解可以在方法上面、类上面、变量上面引用

在xml文件中

添加组件扫描

在使用前先对标签进行修改,添加命名空间context,然后使用context:component-scan标签中的base-package属性设置要扫描的使用了Spring注解的包






    

组件扫描的细节

将属性use-default-filters的值定义为false就告诉Spring不用自带的filter,自己设置过滤内容

context:include-filter的意思是包含这些filter条件的就执行,扫描包含条件的包、类

context:exclude-filter的意思是不包含这些filter条件的就执行,扫描不包含条件的包和类




    
        
    
    
        
    

IOC管理---注解实现属性注入

使用注解进行属性注入时,不用set方法,Spring内部封装了

实现属性注入的注解有:【@AutoWired】、【@Qualifier】、【@Value】、【@Resource】

在service代码中

首先要对定义的属性进行注解创建bean对象【@Repository】

然后在对类进行注解创建bean对象【@Service】、属性注入【@AutoWired】, 他遵守的规则是根据属性类型进行注入,当bean属性只有一个bean对象时

当bean属性有多个备案对象时,需要使用注解【@Qualifier】他根据bean对象的名称进行注入,要先有注解【@AutoWired】,@Qualifier注解作用就像在xml文件中外部bean注入时能选择注入bean对象,ref = bean对象的id



@Service
public class UserService {

//    在属性上方使用@AutoWired注解完成属性注入,这个注解只能对bean类型的属性进行注入
//    @Qualifier注解是跟@AutoWired属性配合起来使用的,它用来声明注入的属性是哪一个类的bean对象
    @Autowired
    @Qualifier(value = "userImpl")
    private UserImpl user;
    public void faa(){
        user.addUser();
        System.out.println(user);
    }
}

@Resource注解既能进行类型注入【bean属性只有一个bean对象】,也能进行名称匹配注入

但是这个注解【@Resource】是Java扩展包Javax的,实际开发中不建议使用



import javax.annotation.Resource;

@Service
public class UserService {

//    在属性上方使用@AutoWired注解完成属性注入,这个注解只能对bean类型的属性进行注入
//    @Qualifier注解是跟@AutoWired属性配合起来使用的,它用来声明注入的属性是哪一个类的bean对象
//    @Autowired
//    @Qualifier(value = "userImplT")
    @Resource(name = "userImplT")
    private UserDao user;
    public void faa(){
        user.addUser();
        System.out.println(user);
    }
}

@value的使用



@Value("name值")
private String name;

IOC管理---完全注解开发

使用配置类代替xml文件,取消xml文件设置,简化文件结构,完全注解开发

在配置类中



//注解@Configuration的作用就是声明当前类为配置类等同与xml问价的作用
@Configuration
//注解@ConponentScan的作用就是声明z扫描的范围,作用跟标签作用一样
@ComponentScan(value = "xlw.com")
public class ConfigUtil {
}

在test类中

使用配置类后没有了xml文件,所以要通过AnnotationConfigApplicationContext类代替ClassPathXmlApplicationContext类来解析配置类



@Test
public void testUserImpl(){
    ApplicationContext context = new AnnotationConfigApplicationContext(ConfigUtil.class);
    UserService userService = context.getBean("userService", UserService.class);
    userService.faa(
    );
}

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

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

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