发表于: 2018-09-09 22:57:42
1 441
今日学习:完成小课堂,重新复习Spring的知识点,IOC和DI概念,Bean的属性,bean的实例化以及对象属性的注入
1.IOC是什么?
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
Bean工厂(BeanFactory接口),提供了基础的依赖注入支持。
应用上下文(ApplicationContext接口),建立在Bean工厂基础之上,提供了系统架构服务。
2.Bean
由IoC容器管理的那些组成你应用程序的对象我们就叫它Bean, Bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。
Bean命名约定:Bean的命名遵循XML命名规范,但最好符合Java命名规范,由“字母、数字、下划线组成“,而且应该养成一个良好的命名习惯, 比如采用“驼峰式”,即第一个单词首字母开始,从第二个单词开始首字母大写开始,这样可以增加可读性。
3.Bean的常用属性
1.id——唯一标识,IoC容器中的bean的id标签不能重复,要求符合XML ID 命名规则
2.name——名称标识,相当于别名也不可重复,基本用不到(解决struts1)遗留问题
3.class——全限定类名,指向classpath下类定义所在位置,就是包名加类名package.classname
4.scope——作用范围,可以设置(singleton,prototype,request,session,globalsession),两个常用的
singleton:单实例,默认值;
prototype:单词本意是原型,这里叫做多实例,意思应该就是以它为原型创建多个实例对象。
配置scope:
<bean id="user" class="com_twg.POJO.User" scope="prototype"/>
测试类:
@Test
public void scopeTest(){
TestIoc ioc=new TestIoc();
//初始化IoC配置文件
ApplicationContext context=ioc.initializeAppContext();
User user1=(User) context.getBean("user");
User user2=(User) context.getBean("user");
System.out.println(user1==user2); //判断两个引用变量是否指向同一对象
/* Student student=(Student) context.getBean("student1");
System.out.println(student);*/
}
输出结果为:false;去掉scope设置,默认为singleton输出结果就会为true,默认情况所有实例对象指向一个实例,只是引用名称不同而已。
4.Bean的实例化方式
1.有参无参构造办法
2.静态工厂
3.实例工厂
实体类
public class User {
public void add(){
System.out.println("执行User对象的add方法!");
}
@Override
public String toString(){
return "创建出一个User对象!";
}
}
静态工厂类
public class UserFactory {
public static User createInstance(){
return new User();
}
实例工厂类
public class UserFactory2 {
public User createInstance2(){
return new User();
}
}
配置文件
1.使用类的无参构造函数-->
<bean id="user" class="com_twg.POJO.User" scope="prototype"/>
<!---->
<!-- 2.使用静态工厂,通过工厂类的某个静态方法创建
等同于user1 = com_twg.test.User.Factory.createInstance()-->
<bean id="user1" class="com_twg.test.UserFactory" factory-method="createInstance"/>
<!-- 3.使用实例工厂,通过工厂类的某个实例方法创建
等同于userFactory = new com_twg.test.UserFactory2()-->
<bean id="userFactory2" class="com_twg.test.UserFactory2"/>
<!--等同于user2= usrFactory.createInstance();-->
<bean id="user2" factory-bean="userFactory2" factory-method="createInstance2"/>
测试类
@Test
public void runUser(){
//1.加载Spring配置文件,创建对象
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获得配置了bean的User对象,用构造函数的方式new出一个User对象user
User user=(User) context.getBean("user");
System.out.println(user);
user.add();
//3.通过静态工厂直接调用静态方法创建User对象user1
User user1=(User) context.getBean("user1");
System.out.println(user1);
user1.add();
//4.通过实例工厂,先实例化工厂类,在通过调用工厂类中的方法创建User对象user2
User user2=(User) context.getBean("user2");
System.out.println(user2);
user2.add();
}
}
结果
可以就看到三种方式所达到的效果都是在IOC中注入Bean,功能没有区别
5.bean的属性注入方式:
1.有参构造注入
2.set方法
3.P名称属性注入
4.接口的方法(几乎用不到),不介绍有兴趣自己去学习。
实体类
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
/* public void setName(String name) {
this.name = name;
}*/
@Override
public String toString(){
return "创建对象Student{"+"name='"+name+'\''+'}';
}
}
1有参函数配置
<!--1.配置有参构造函数提供属性注入-->
<bean id="student" class="com_twg.POJO.Student">
<constructor-arg name="name" value="DreamBoy"/>
</bean>
2.set方法配置
<!--2.配置set函数提供属性注入-->
<bean id="student1" class="com_twg.POJO.Student">
<property name="name" value="Harry"/>
</bean>
3.P名称配置
<!--p名称空间注入属性-->
<bean id="student2" class="com_twg.POJO.Student" p:name="Hermione"/>
这个需要在头文件中加上
xmlns:p="http://www.springframework.org/schema/p"
这三种方式除了在Ioc中注入Student类的Bean外,还给在创建Bean的实例对象时给属性name赋值,这三种方式功能和效果也没有区别。
6.bean的自动注解方式
最开始Spring只有@Component,不过为了阅读性,以及让注解的用途清晰,衍生出了下面三个:
@Controller web层; @Service 业务层; @Repository 持久层。
@Repository 只能标注在 DAO 类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
评论