Spring IOC控制反转

tech2022-08-11  133

Spring IOC

IOC 控制反转的思想,DI依赖注入是IOC的具体实现方法

利用xml配置文件,来创建对象

注入依赖:

根据setter方法根据有参构造函数

注入空值

注入带有符号的属性值:

把<>进行转义&lt, &gt(直接在特殊符号)

value="&lt;<white> &gt"

把带有特殊符号的内容写到CDATA中

<!--特殊符号的注入--> <constructor-arg name="color" ><value><![CDATA[<<<白色>>>]]]]></value>

注入外部bean:

将外部的对象作为本类的属性,并添加set方法:将本类的bean的值value,也就是ref,设置为外部类的id public class Service { Dao dao=new DaoImpl(); public void setDao(Dao dao) { this.dao = dao; } public void testDao() { dao.display(); } } <bean id="service" class="com.robin.service.Service"> <property name="dao" ref="daoImpl"></property> </bean> <bean id="daoImpl" class="com.robin.dao.DaoImpl"></bean>

注入内部类(一对多),级联赋值:同样的方法,只不过在多方的bean中,嵌套少方的bean

<bean id="emp" class="com.robin.InnerBean.Emp"> <property name="eName" value="robin"></property> <property name="gender" value="male"></property> <property name="dept"> <bean id="dept" class="com.robin.InnerBean.Dept"> <property name="dName" value="HR"></property> </bean> </property> </bean> <!--级联赋值--> <bean id="emp" class="com.robin.InnerBean.Emp"> <property name="eName" value="robin"></property> <property name="gender" value="male"></property> <property name="dept" ref="dept"></property> </bean> <bean id="dept" class="com.robin.InnerBean.Dept"> <property name="dName" value="HR"></property> </bean>

注入集合类型属性:

<bean id="student" class="com.robin.Collection.Student"> <property name="courses"> <array> <value>math</value> <value>english</value> </array> </property> <property name="hoddy"> <list> <value>play game</value> <value>read book</value> <value>eat</value> </list> </property> <property name="grdens"> <map> <entry key="math" value="99"></entry> <entry key="english" value="80"></entry> </map> </property> <property name="friends"> <set> <value>10</value> <value>20</value> </set> </property> </bean>

注入集合类对象

property name="hobbylist"> <list> <ref bean="hobby1"></ref> <ref bean="hobby2"></ref> </list> </property> </bean> <bean id="hobby1" class="com.robin.Collection.Hobby"> <property name="hname" value="game"></property> </bean> <bean id="hobby2" class="com.robin.Collection.Hobby"> <property name="hname" value="eat"></property> </bean>

将集合注入部分提取出来:先创建util空间,在创建对象

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean id="student" class="com.robin.Collection.Sudent"> <util:list id="computer"> <value>dele</value> <value>xiaomi</value> <value>huawei</value> </util:list> <bean id="computerya" class="com.robin.Collection.computer"> <property name="list" ref="computer"></property> </bean>

定义类型和返回类型可以不一致

public class Book implements FactoryBean<Dept> { @Override public Dept getObject() throws Exception { // Dept dept=new Dept(); // dept.setdName("HR"); // return dept; ApplicationContext context=new ClassPathXmlApplicationContext("beans6.xml"); Dept dept = context.getBean("book2",Dept.class); return dept; }

spring的作用于(单例对象和多例对象):在xml文件中,加上scope属性,

<bean id="book2" class="com.robin.InnerBean.Dept" scope="singleton">单例 <bean id="book2" class="com.robin.InnerBean.Dept" scope="prototype">多例

spring 的生命周期:五步和七步(多了一个在初始化之前的bean后置处理器,和一个初始化之后的bean后置处理器)

package com.robin.LifePost; public class Door { private String dName; public Door() { System.out.println("第一步,执行无参数构造实例"); } public void setdName(String dName) { this.dName = dName; System.out.println("第二部,在set方法中设置属性值"); } public void initMothod(){ System.out.println("第三部,执行初始化方法"); } public void destroyMothod() { System.out.println("第五部,销毁对象"); } } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="door" class="com.robin.LifePost.Door" init-method="initMothod" destroy-method="destroyMothod"> <property name="dName" value="hongxing"></property> </bean> <bean id="post" class="com.robin.LifePost.Post"> </bean> </beans> package com.robin.LifePost; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestPost { @Test public void test(){ ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml"); Door door=context.getBean("door",Door.class); System.out.println("第四部,实例化对象"); // 销毁对象 ((ClassPathXmlApplicationContext) context).close(); } } package com.robin.LifePost; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; //实现BeanPostProcessor接口,实现里面的before和after方法 public class Post 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; } }

自动装配:bean中的aotowire属性值为byName和byType。byType只能装配一个类的一个对象,

<!--自动装配,aotowire: byName和byType--> <bean id="basketball" class="com.robin.AutoWire.Basketball" autowire="byType"> </bean> <bean id="bool" class="com.robin.AutoWire.Bool"></bean> <!--<bean id="bool2" class="com.robin.AutoWire.Bool"></bean>-->

通过引入外部文件类配置

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--直接配置--> <bean id="dataSource" class="com.alibaba.druid.DruidDataSource"> <property name="dirveClassName" value="com.mysql.jdbc.Dirve"></property> <property name="url" value="jdbc:mysql://localhost:3306/robin"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!--外部引入配置--> <context:property-placeholder local-override="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.DruidDataSource"> <property name="dirveClassName" value="${dirveClassName}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.username}"></property> <property name="password" value="${prop.password}"></property> </bean> </beans> prop.dirveClassName:com.mysql.jdbc.Dirve prop.url:jdbc:mysql://localhost:3306/robin prop.username:root prop.password:root

注解的使用:

注解是代码的特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值)使用注解,注解作用在类上面,方法上面,属性上面使用注解的目的,简化xml配置 类的注解有Component,Service,Controller,Repository,这几个一般情况下效果是一样的,但是一般使用的时候,Service用在业务层,Component用在Web层,Repository用在持久层 <!--开启注解扫描--> <context:component-scan base-package="com.conpoent"></context:component-scan> //使用注解的方式创建对象 //注解后面的Value值表示的是定义本类对象的别名,如果不设置的话,默认是类名首字母小写的别名 @Component(value = "tcs") public class TestComponentScan { public void display(){ System.out.println("这是一个注解的类"); } }

使用指定的注解和不使用指定的注解去扫描包

<!--扫描指定的注解--> <context:component-scan base-package="com.conpoent" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter> </context:component-scan> <!--不扫描指定的注解--> <context:component-scan base-package="com.conpoent"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter> </context:component-scan>

使用@Qualifier和@Autowired一起使用,这个是通过指定要注入的类名(在多个类实现同一个接口的时候,就需要制定往哪个类里面去注入)

@Service public class Library { @Autowired @Qualifier(value = "book1") private Book book; public void testLibrary() { System.out.println("我是一个图书馆,里面藏有很多书籍!"); book.displayshu(); } }

使用@Resource来指定要注入的类的类型,使用@Resource(name=“book1”)用来根据名称来注入

//@Resource @Resource(name = "book1") private Book book;

使用@Value表示注入一般类型的值

@Value("tianjin") private String loc;

纯注解方式开发,不使用配置文件

先生成一个配置类

@Configuration @ComponentScan(basePackages = "com.robin.Spring5") public class SpringConfig { }

在测试类中,解析XMl的要改成:

ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
最新回复(0)