Spring杂项学习(IOC)

来源:互联网 发布:java mainframe 编辑:程序博客网 时间:2024/05/22 10:49

一、IOC容器介绍

就是具有依赖注入功能的容器,是可以创建对象的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。

【1】搭建Spring IOC容器需要的开发环境

①导入jar包

②创建Spring配置文件[Spring bean Configuration File]一般命名为applicationContext.xml

二、IOC容器细节

【0】IOC容器在Spring中的实现

IOC容器的两种实现方式:

(1)BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身

(2)ApplicationContext:BeanFactory的子接口,提供了更多高级特性

ApplicationContext的主要实现类

ClassPathXmlApplicationContext:对应类路径下的XML格式的配置文件

FileSystemXmlApplicationContext:对应文件系统中的XML格式的配置文件

【1】通过IOC容器创建对象

<!-- 需要由IOC容器创建对象的全类名 --><!-- 为了便于从IOC容器中获取book对象,声明一个一个唯一的id值 -->
<bean id="book01" class="com.neuedu.spring.bean.Book"><property name="bookId" value="2001"></property><property name="bookName" value="三国演义"></property></bean>
@Testpublic void test01() {//1.创建IOC容器自身的对象//指定配置文件以类路径为基准的配置文件名ApplicationContext ioc= new ClassPathXmlApplicationContext("bean.xml");//2.从IOC容器中获取指定的对象Object bean = ioc.getBean("book01");System.out.println(bean);}
注意:
①IOC容器本身对象创建时,会将配置文件中配置好的bean先创建出来
②默认是单实例的,只创建bean的一个对象
③如果设置bean的scope属性为prototype,那么创建bean的对象就是多实例的,在获取的时候创建,每次获取对象都会创建新的
④.从IOC容器中获取对象
①根据bean的id获取
②根据bean的类型获取:要求容器中指定类型的bean是唯一的
⑤创建对象时调用的是对象的默认无参构造方法,而给对象属性赋值则是同set方法赋值

【2】bean的属性赋值

①通过bean的property调用类的set方法

 ②通过bean的构造器赋值

     <bean id="book" class="com.neuedu.spring.bean.Book" >       <constructor-arg value= "10010"/>       <constructor-arg value= "Book01"/>       <constructor-arg value= "Author01"/>       constructor-arg value= "20.2"/>
调用Book类的构造方法

 ③通过索引值指定参数位置(index)

 ④通过类型不同区分重载的构造器(type)

 ⑤bean的级联属性赋值

 ⑥p名称空间

<bean id="studentSuper" class="com.neuedu.helloworld.bean.Student" p:studentId="2002" p:stuName="Jerry2016" p:age="18" />

【3】ioc容器中bean对象创建的时机

bean对象是在ioc容器创建的时候同时被创建,当是多实例的bean对象时,是在每次获取该bean对象的时候创建

【4】bean之间的依赖

<bean>标签下的depends-on决定了在这个bean创建前需要先创建哪个bean

【5】通过继承实现bean配置信息重用

<bean>标签下的parent

【6】通过abstract属性创建模板bean

设置需要作为模板的beanabstract属性为true

【7】引用其它bean

通过<bean>标签下的<property>标签属性ref指向
【8】使用list集合属性
通过<list>
 <bean id="shop" class="com.neuedu.spring.bean.Shop" >     <property name= "categoryList">        <!-- 以字面量为值的List集合 -->        <list>           <value> 历史</value >           <value> 军事</value >        </list>      </property>     <property name= "bookList">     <!-- 以bean的引用为值的List集合 -->     <list>        <ref bean= "book01"/>        <ref bean= "book02"/>     </list>     </property></bean >

【9】使用map集合属性

<bean id="cup" class="com.neuedu.spring.bean.Cup"><property name="bookMap"><map><entry><key><value>bookKey01</value></key><ref bean="book01"/></entry><entry><key><value>bookKey02</value></key><ref bean="book02"/></entry></map></property></bean>

【10】配置通过静态工厂方法创建的bean[通过静态方法提供实例对象,工厂类本身不需要实例化!]

<bean id="staticFactory" class="com.neuedu.spring.bean.StaticFactory" factory-method="getBook"><constructor-arg value="book01"></constructor-arg></bean>
只要在class类中有factory-method对应的静态方法

【11】配置通过实例工厂方法创建的bean[通过实例方法提供实例对象,工厂类本身需要先创建对象!]

<bean id="instanceFactory" class="com.neuedu.spring.bean.InstanceFactory"></bean><bean id="bookFromInstanceFactory" factory-bean="instanceFactory" factory-method="getBook"><constructor-arg value="book02"></constructor-arg></bean>

【12】工厂bean配置FactoryBean


public class MyFactoryBean implements FactoryBean<Book> {@Overridepublic Book getObject() throws Exception {return new Book(22, "无字天书", "好啊", 22.5);}@Overridepublic Class<?> getObjectType() {return Book.class;}@Overridepublic boolean isSingleton() {return false;}}

【13】bean的后置处理器

在bean的初始化方法调用前后执行操作的专门的对象

    —添加bean后置处理器后bean的生命周期

[1]通过构造器或工厂方法创建bean实例

[2]为bean的属性设置值和对其他bean的引用

[3]将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法

[4]调用bean的初始化方法

[5]将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法

[6]bean可以使用了

[7]当容器关闭时调用bean的销毁方法

三、C3P0数据库连接池

【1】连接池解释

> 数据库连接池就是存放数据库连接(Connection)的集合
> 我们获取一个数据库连接是一个相对很麻烦的过程,
如果我们获取一个数据库连接,使用一次以后就给它关闭了
下一次再去使用的时候就要重新创建一个新的数据库连接。
> 所以我们提出了一个数据库连接池的概念,数据库连接池放的都是数据库连接(Connection)
我们在去使用数据库连接时候,不用再去重新创建数据库连接,而是直接从池中获取,
使用完的数据库连接,也不是直接销毁,而是要放回到连接池。

【2】引用外部属性文件

//jdbc.properties文件:jdbc.user=rootjdbc.passowrd=123456jdbc.url=jdbc:mysql://localhost:3306/testjdbc.driver=com.mysql.jdbc.Driver<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 根据外部属性文件中的信息配置数据源 --><bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.passowrd}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="driverClass" value="${jdbc.driver}"></property></bean>
如何通过连接池调用数据库
ComboPooledDataSource bean = ioc.getBean(ComboPooledDataSource.class);Connection connection = bean.getConnection();System.out.println(connection);Statement st = connection.createStatement();ResultSet rs = st.executeQuery("select * from stu");while(rs.next()){String string = rs.getString("name");String string2 = rs.getString("school");System.out.println(string+"==="+string2);}

四、注解配置bean、XML属性装配

【1】基于XML属性装配(对类下的属性进行装配)

①手动装配
<!-- 属性的装配:手动装配 --><bean id="userService" class="com.neuedu.spring.bean.UserService"></bean><bean  id="userAction" class="com.neuedu.spring.bean.UserAction"><property name="userService" ref="userService"></property></bean>
②自动装配
<!-- 1.按类型装配:byType --><!-- 首先检测当前bean中需要装配的属性的类型 --><!-- 然后在IOC容器中查找匹配这个类型的bean --><!-- 如果类型匹配的bean是唯一的,那么就将这个匹配的bean注入到userAction中 --><bean id="userService" class="com.neuedu.spring.bean.UserService"></bean><bean  id="userAction" autowire="byType" class="com.neuedu.spring.bean.UserAction"></bean>
<!-- 2.按bean的id值装配:byName --><!-- 首先检测当前bean中需要装配的属性的属性名,属性名是将setXxx()方法去掉set,首字母小写得到的 --><!-- 然后根据属性名作为id的值,在IOC容器中查找对应的bean --><!-- 如果能够找到,则将找到bean注入进去 -->

【2】注解配置bean

①声明bean的注解
@Component 将当前类声明为IOC容器中的一个普通的组件
@Controller 将当前类声明为IOC容器中的一个控制器组件
@Service 将当前类声明为IOC容器中的业务逻辑层组件
@Repository 将当前类声明为IOC容器中的一个持久化层组件
②使用基于注解的bean的配置,需要额外导入一个jar包:spring-aop-4.0.0.RELEASE.jar
③需要设置自动扫描的包
< context:component-scan base-package ="com.neuedu.ioc.bean"/>
④使用注解后,默认按照类名首字母小写作为id的值,也可以使用value属性指定id

【3】扫描包中类

①context:include-filter指定扫描包时要包含的类
通过将use-default-filters属性设置为false,禁用默认过滤器,然后扫描的就只是include-filter中的规则指定的组件
            context:exclude-filter指定扫描包时不包含的类   

【4】使用@Autowired注解实现根据类型实现自动装配

①首先检测标记了@Autowired注解的属性的类型
②根据类型进行装配
③如果指定类型的bean不止一个,那么根据需要被装配的属性的属性名做id的值,查找bean
④]如果根据id值还是没有找到bean,可以使用@Qualifier注解手动指定要装配的bean的id.