spring5学习第二天--ioc控制反转(2)

1.IOC操作Bean管理(FactoryBean)

普通Bean:在配置文件中定义的类型就是返回的类型

工厂bean:在配置文件中定义的类型可以不是不是返回的类型

工厂bean实现FactoryBean接口即可

public class MyBean implements FactoryBean<Course> {
    //定义返回对象类型
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setcName("factorybean");
        return course;
    }

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

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

<bean id="myBean" class="com.jcy.spring5.collection.factorybean.MyBean">

</bean>

通过factorybean来配置bean的实例,但是实际返回的是实例确实是factorybean的getobject()方法返回的实例

2.bean的作用域(单例/多例)

几种作用域中,request、session作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于web的Spring ApplicationContext环境。

Singleton

当一个bean的作用域为Singleton,那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。

在加载配置文件时就创建了实例对象

<bean id="user" class="com.jh.domain.User" scope="singleton"/>

Prototype

表示一个bean定义对应多个对象实例,Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。

Prototype是原型类型它在我们创建容器的时候没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。

<bean id="user" class="com.jh.domain.User" scope="prototype" />

Request

当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例

即每一个HTTP请求,都会单独创建一个bean,若请求结束,bean也会随之销毁。

使用request作用域一般不会存在线程安全问题,因为在Web应用中,每个请求都是由一个单独的线程进行处理,所有线程之间并不会共享bean,从而不会存在线程安全的问题。

如果使用的是注解扫描配置bean,那么在bean所属的类上使用@RequestScope注解即可使用此作用域,若是基于xml文件,则通过beanscope配置项:

<bean id="loginAction" class="com.something.LoginAction" scope="request"/>

Session

Session作用域将bean的使用范围一次在一次http会话中,对于每一个会话,Spring容器都会创建一个单独的bean,若Session被销毁,则bean也随之销毁。

<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>

Application

Spring 容器通过为整个 Web 应用程序使用一次 bean 定义来创建 bean 的新实例。也就是说,bean 在级别上进行范围范围存储,并存储为常规属性。

这与 Spring Singleton Bean有些类似,但在两个重要方面有所不同:它是每个的单元,而不是每个 Spring"应用程序上下文"(对于它,在任何给定的 Web 应用程序中可能有多个),它实际上是公开的,因此作为属性可见。‎

application作用域也只能用于web应用中。使用方式和之前几种类似,可以通过@ApplicationScope注解,也可以使用xml配置文件:

<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

3.Bean的生命周期

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

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

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

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

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

public void testdemo4(){
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("获取bean实例-----4");
        System.out.println(orders);
        context.close();
    }
//结果
//无参构造创建bean----1
//set方法设置属性值-----2
//执行初始化方法-----3
//获取bean实例-----4
//Orders{oName='iqooneo5'}
//销毁bean实例-----5
public void initMethod(){
    System.out.println("执行初始化方法-----3");
}
public void destoryMethod(){
    System.out.println("销毁bean实例-----5");
}
public Orders() {
        System.out.println("无参构造创建bean----1");
    }

    public void setoName(String oName) {
        this.oName = oName;
        System.out.println("set方法设置属性值-----2");
    }
</bean>
    <bean id="orders" class="com.jcy.spring5.collection.factorybean.Orders" init-method="initMethod" destroy-method="destoryMethod">
        <property name="oName" value="iqooneo5">

        </property>
    </bean>

Spring当中的后置处理器是Spring体用的一个扩展点,开发者只要去实现,Spring当中的BeanPostProcessor接口,那么就能插手SpringBean实例化的一个过程

BeanPostProcessor 接口也被称为后置处理器,通过该接口可以自定义调用Bean初始化前后执行的操作方法。

如果我们希望容器中创建的每一个bean,在创建的过程中可以执行一些自定义的逻辑,那么我们就可以编写一个类,并让他实现 **BeanPostProcessor** 
接口,然后将这个类注册到一个容器中。

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

4.自动装配

手动装配是通过value标签装入属性值,自己配置

<bean id="orders" class="com.jcy.spring5.collection.factorybean.Orders" init-method="initMethod" destroy-method="destoryMethod">
        <property name="oName" value="iqooneo5">
        </property>
 </bean>

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

<bean id="emp" class="com.jcy.spring5.autowire.Emp" autowire="byName">
<!--    <property name="dept" ref="dept"></property>-->
</bean>
<bean id="emp" class="com.jcy.spring5.autowire.Emp" autowire="byType">
</bean>

5.引入外部属性文件

1、直接配置数据库信息,配置德鲁伊连接池

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${prop.driverClass}"></property>
    <property name="url" value="${prop.url}"></property>
    <property name="username" value="${prop.userName}"></property>
    <property name="password" value="${prop.password}"></property>
</bean>
<context:property-placeholder location="jdbc.properties"></context:property-placeholder>
prop.driverClass=com.mysql.cj.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=123456

IOC 操作 Bean 管理(基于注解方式)

Spring 针对 Bean 管理中创建对象提供注解:注解可以简化xml配置

(1) @Component:把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>

(2) @Service:服务(注入dao)

(3) @Controller:控制器(注入服务)

(4) @Repository:dao(实现dao访问)

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

开启组件扫描:指明扫描包的名称

<context:component-scan base-package="com.jcy.spring5.annocation">
 </context:component-scan>
//创建了bean实例
//value不加的话默认是类名首字母小写
@Component(value = "userService")
//@Service
public class UserService {
    public void add(){
        System.out.println("add-----");
    }
}
@Test
    public void testDenmo1(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean5.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
        System.out.println(userService);
    }
//add-----
//com.jcy.spring5.annocation.service.UserService@544fa968

开启组件扫描细节配置:开启组件扫描之后不配置默认会扫描包中所有的注解

<!--示例 1
use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
context:include-filter ,设置扫描哪些内容,下面只扫描Controller
-->
<context:component-scan base-package="com.jcy" use-default-filters="false">
        <context:include-filter type="annotation"
                               expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--示例 2
        下面配置扫描包所有内容
        context:exclude-filter: 设置哪些内容不进行扫描
下面就是不扫描controller
 -->
<context:component-scan base-package="com.jcy">
    <context:exclude-filter type="annotation"
                            expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

基于注解方式属性注入

@Autowired:**根据属性类型(byType)**进行自动装配

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

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

@Qualifier:根据名称(byname)进行注入

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

@Service
public class UserService {
    @Autowired
		@Qualifier(value = "userDaoImpl")
    private UserDao userDao;

    public void add(){
        System.out.println("add-----");
        userDao.add();
    }
}
@Repository
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("dao add======");
    }
}

@Resource:可以根据类型注入,可以根据名称注入,就类似与autowire和qualifier二者的替代品

@Resource

@Resource(name = "userDaoImpl")

@Value:注入普通类型属性

前三者针对对象类型的注入,而value针对普通类型的注入

纯注解开发

用配置类替代xml配置文件

@Configuration
@ComponentScan(basePackages = "com.jcy")
public class SpringConfig {
}
@Test
    public void testDemo01(){
        ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
        System.out.println(userService);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值