https://www.cnblogs.com/nwu-edu/p/9542074.html
用spring的方式创建一个对象实例
package com.wang.Spring5;
?
public class User {
public void add(){
System.out.println("add>>>>>>");
}
}
测试
IOC是什么,能做什么,怎么做到的
什么是Bean管理:(两个操作)
1、Spring创建对象
2、Spring注入属性
<!--配置User对象创建-->
<!--这里的意思是给com.wang.Spring5.User起了一个别名-->
<bean id="user" class="com.wang.Spring5.User"></bean>
?
?
//1、在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
//2、在bean标签有很多属性,介绍常用的属性
*id属性:唯一标识(别名)
*class属性:类的全路径
*name属性:很少用,类似于id
//3、创建对象时,默认使用无参构造函数创建(没有的话就会报错)
DI:依赖注入(注入属性)(Dependency Insert)
IOC和DI的区别:DI是IOC的一种具体实现,是在创建了对象的基础上操作的
<bean id="book" class="com.wang.Spring5.Book">
<property name="bname" value="书名1"></property>
<property name="time" value="2001"></property>
</bean>
<bean id="order" class="com.wang.Spring5.Order">
<constructor-arg name="oname" value="12"></constructor-arg>
<constructor-arg name="address" value="江西"></constructor-arg>
</bean>
——另一种方式(通过索引)
<bean id="order" class="com.wang.Spring5.Order">
<constructor-arg index="0" value="34"></constructor-arg>
<constructor-arg index="1" value="北京"></constructor-arg>
</bean>
-- 含null <constructor-arg name="oname"> <null></null> </constructor-arg> -- 含<>符号 <constructor-arg name="address"> <value><![CDATA[<<北京>>]]></value> </constructor-arg>
可以理解为一个bean对象的属性指向另一个bean对象 1、创建service类和dao类 2、在service中调用dao里的方法
- 外部bean <bean id="userService" class="com.wang.service.UserService"> <!--注入userDao对象 name属性:类里面属性名称 ref属性:创建userDao对象bean标签id --> <property name="userDao" ref="userDao"></property> </bean> <bean id="userDao" class="com.wang.dao.UserDaoImp"></bean> - 内部bean:和上面那一种方法达到的效果是一样的 <bean id="emp" class="com.wang.company.Employee"> <property name="ename" value="wangwang"></property> <property name="eage" value="18"></property> <property name="dept"> <bean id="dept" class="com.wang.company.Department"> <property name="dname" value="安保部门"></property> </bean> </property> </bean> - 级联复制(一般不用) <bean id="emp" class="com.wang.company.Employee"> <property name="eage" value="18"></property> <property name="ename" value="wang"></property> <property name="dept" ref="dept"></property> <property name="dept.dname" value="人力资源部"></property> </bean> <bean id="dept" class="com.wang.company.Department"></bean>
在对象里设置集合类型
public class Person { //1.数组类型属性 private String[] array; //2.list集合类型属性 private List<String> list; //3.map集合类型属性 private Map<String, String> map; //4.set集合类型属性 private Set<String> set; }
<bean id="ryan" class="com.ryan.spring5.inputCollection.Person"> <!--数组类型属性注入--> <property name="array"> <array> <value>arr1</value> <value>arr2</value> </array> </property> <!--list类型属性注入--> <property name="list"> <list> <value>list1</value> <value>list2</value> </list> </property> <!--map类型属性注入--> <property name="map"> <map> <entry key="map-key1" value="map-value1"></entry> <entry key="map-key2" value="map-value2"></entry> </map> </property> <!--set类型属性注入--> <property name="set"> <set> <value>set1</value> <value>set2</value> </set> </property> </bean>
在集合里面设置对象类型值
理解:即处理下面这种数据,集合里面是示例对象的情况
private List<Family> familyList; public void setFamilyList(List<Family> familyList) { this.familyList = familyList; }
操作:使用了ref标签里的bean属性
<bean> <property name="familyList"> <list> <ref bean="family"></ref> <ref bean="family"></ref> <ref bean="family"></ref> </list> </property> </bean> <bean id="family" class="com.wang.gather.Family"> <property name="f" value="13"></property> </bean>
把集合注入部分提取出来
理解:即把下面这个部分独立出来,便于多次调用,有点类似于创建一个公用数组,这样大家都可以调用了
<property name="array"> <array> <value>arr1</value> <value>arr2</value> <value>arr3</value> </array> </property>
操作
<!--这个地方类似于一个公开数组--> <util:list id="list1"> <value>张辽</value> <value>hello</value> <value>太死</value> </util:list> <bean id="person" class="com.wang.gather.Person"> <property name="list" ref="list1"></property> </bean>
工厂bean的作用:用java代码来代替一些比较赋值比较麻烦的bean,通过在xml文件中配置我们的工厂bean,然后在工厂bean中实现返回配置好的我们需要的bean,然后我们接收这个bean时只需要引入这个工厂bean的id即可
Spring有两种类型的bean, 一种普通bean, 一种工厂bean(FactoryBean)
普通Bean: 在配置文件中定义的bean类型就是返回类型;
工厂bean: 在配置文件中定义的bean类型可以和返回类型不一样,
有点意思是传入一个参数得到另外一个参数
怎么创建Factorybean
(1)创建类, 实现接口FactoryBean;
(2) 实现接口里面的方法, 在实现的方法中定义返回的bean类型.
Mybean
package com.wang.Factorybean; public class Mybean { //只要一个名字 private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Mybean{" + "name=‘" + name + ‘\‘‘ + ‘}‘; } }
MybeanImp
public class MybeanImp implements FactoryBean<Mybean> { public Mybean getObject() throws Exception { //在这个地方完成对mybean的配置 Mybean mybean = new Mybean(); mybean.setName("dashazi"); return mybean; } public Class<?> getObjectType() { return null; } public boolean isSingleton() { return false; } }
xml文件
<!--注意创建的是工厂bean--> <bean id="mybean" class="com.wang.Factorybean.MybeanImp"></bean>
实现
@Test public void test7(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Mybean mybean = context.getBean("mybean", Mybean.class); System.out.println(mybean); }
单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的;
多例则指每个请求用一个新的对象来处理,比如action;
如何设置单例和多例
可以用Spring配置文件bean标签里面的scope属性, 来设置单实例/多实例.
Spring默认单实例, 即scope=singleton
可以通过设置scope=prototype来设置多实例
如:
<bean id="testBean" class="com.ryan.spring5.testScope.TestBean" scope="prototype"></bean>
这就是一个多例对象
singleton和prototype区别
singleton单例,prototype多例
设置scope值是单例时,加载spring配置文件时就会创建单实例对象,而scope值时多例对象时,加载spring配置文件时不会创建对象,使用getbean方法时才会调用
另外还有:request(一次请求),session(一此对话),不做解释
具体步骤
通过构造器创建bean实例(无参数构造);
设置bean的属性值和对其他bean引用(调用set方法);
*(可以不进行)**把bean实例传递给bean后置处理器的方法postProcessBeforeInitialization
调用bean的初始化的方法(需要配置初始化方法);
*(可以不进行)**把bean实例传递给bean后置处理器的方法postProcessAfterInitialization
bean可以使用了(获取到了对象);
当容器关闭的时候, 调用bean的销毁方法(需要配置销毁方法)
演示
public class Orders { private String name; public Orders() { System.out.println("1、无参数构建"); } public void setName(String name) { this.name = name; System.out.println("2、调用set方法"); } public void add(){ System.out.println("6、获取到了对象"); } //初始化方法,对应initMethod属性 public void initMethods(){ System.out.println("4、调用初始化方法"); } //销毁方法,对应destroyMethod属性 public void destroyMethods(){ System.out.println("5、调用销毁方法"); } }
public class MybeanPost implements BeanPostProcessor {
?
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("3、初始化前的操作");
return bean;
}
?
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("5、初始化之后的操作");
return bean;
}
}
<bean id="orders" class="com.wang.Factorybean.Orders" init-method="initMethods" destroy-method="destroyMethods">
<property name="name" value="hello世家"></property>
</bean>
?
<!--后置处理器-->
<bean id="beanpost" class="com.wang.Factorybean.MybeanPost"></bean>
<!--注意点:后置处理器一旦在xml文件中实例化,所有的bean示例都会配置这个处理器-->
自动装配: 根据指定装配规则(属性名称或属性类型), Spring自动将匹配的属性值进行注入
根据名字匹配
<!--原来的配置方式-->
<!-- <bean id="dep" class="com.wang.autowire.Dep"></bean>-->
<!-- <bean id="emp" class="com.wang.autowire.Emp">-->
<!-- <property name="dep" ref="dep"></property>-->
<!-- </bean>-->
?
<!--后来的配置方式-->
<bean id="emp" class="com.wang.autowire.Emp" autowire="byName"></bean>
<!--它会根据emp里的属性的名称自动匹配id也式同样名字的属性-->
<bean id="dep" class="com.wang.autowire.Dep"></bean>
根据类型匹配
注意点:一旦自动装配选择了bytype,那么我们需要的那个属性的类就只能创建一个实例
<bean id="emp" class="com.wang.autowire.Emp" autowire="byType"></bean>
?
<bean id="dep" class="com.wang.autowire.Dep"></bean>
首先需要配置命名命名空间
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">
调用外部属性
prop.driverClass = com.mysql.jdbc.Driver
prop.url = jdbc:mysql://localhost:3306/userDB
prop.userName = root
prop.password = 123456
<!--引入外部文件配置数据库-->
<context:property-placeholder location="classpath:bean.properties"></context:property-placeholder>
<!--调用数据-->
<bean id="myjdbc" class="com.wang.jdbc.MyJdbc">
<property name="driverClass" 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>
注解是代码标记,格式:@注解名称(属性名称=属性值,属性名称=属性值)
使用注解配置的目的:简化xml配置
spring针对bean对象管理有四个注解
注意的是这些注解的底层是一样的,只不过为了逻辑更加清晰
@Component 用于普通组件
@Service 用于业务逻辑层
@Controller 用于web层
@Repository 用于dao层
开启组件扫描:分两步: 引入context名称空间 -> 设置要扫描的包
<?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"> <!--开启组件扫描, 要扫描多个包则用逗号隔开--> <context:component-scan base-package="com.wang.dao,com.wang.service"></context:component-scan> </beans>
创建类调用注解
//这个等价于<bean id="userservice" class="全类名"> //可以默认不写:不写的话value值就是类的名称首字母小写 @Component(value = "userservice") public class UserService { public void add(){ System.out.println("add________________"); } }
测试调用
@Test public void test1(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean_1.xml"); UserService userservice = context.getBean("userservice", UserService.class); System.out.println(userservice); }
经过测试调用,发现事实上注解的作用就是把那个对应的类帮助我们在xml文件里简化了开发而已,并不是另起炉灶,所以我们获取实例对象仍然是在使用原来的方式获取
可以令一些配置组件不被扫描,而另外一些配置组件扫描
只扫描部分组件
<context:component-scan base-package="com.wang.dao,com.wang.service" use-default-filters="false"> <!--设置只监听特定注解的内容--> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
设置不扫描部分组件
<context:component-scan base-package="com.wang.service,com.wang.dao" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>
属性注入的注解
@Autowired: 根据属性类型进行自动装配
@Qualifier: 根据属性名称进行注入
@Resource: 可以根据类型注入, 可以根据名称注入
@Value: 注入普通类型属性
@Autowired和@Qualifier注解
//先创建一个实例
@resource注解
//根据属性注入
@Value注解
@Value(value = "13")
private int age;
可以使用配置类代替配置文件, 从而使用纯注解来写代码(一般使用在SpringBoot中)
新建SpringConfig类并添加注解, 以代替原来的xml文件:
//作为配置类,替代xml配置文件
改写测试程序
原文:https://www.cnblogs.com/CoderWangEx/p/14854802.html