初见Sping之Bean
来源:互联网 发布:如何制作淘宝宝贝长图 编辑:程序博客网 时间:2024/05/21 15:50
初见Sping之Bean
Spring一款优秀的开源框架,现在已经成为了java开发的标配框架,Spring框架提供的主要特性便是IOC(Inversion of control,控制反转)和DI(Dependency Injection,依赖注入)。这两个概念紧密联系,却又有些许不同。
一丶依赖注入和控制反转
(1)Spring 中的控制反转是基于这样的一种场景:
User user =new User();
上述获取对象的方法是直接new出来,对象何时new,在哪里new都是客户端代码直接决定的,这称为硬性编码。
User user =spring.getUser();
上述获取对象的方法是通过一个方法得到的,对象何处创建,创建的对象究竟是User的实例还是User的子类实例等等都是由applicationContex这个容易决定的,想对应的可以称为软编码。从硬性编码到软编码的过程中对象控制权限发生了转移,由客户端的代码转移到了spring,这种过程就是控制反转的含义,就是工厂设计模式的一种体现。
(2)依赖注入
依赖注入是基于控制反转概念上的一种延伸,个人理解是对控制反转这种思想的具体应用。考虑如下情景。
class UserService{ publicUserDao userDao;}class UserDao{}
UserService是一个类,UserDao是其的一个成员变量,在这种情况下Userservice依赖UserDao,UserDao是被依赖类。在spring实现控制反转的概念上,spring需要创建一个Userservice对象,那么对Userservice对象所依赖的UserDao对象进行赋值的过程就是依赖注入,说白了就是一个赋值的过程,只是这个赋值的方法和过程由Spring管理,这点上联系了依赖注入的概念。
二丶Spring在控制反转上的体现
Spring管理Bean对象的创建是IOC的一种体现,本文主要总结Spring创建Bean对象方式。
(1)直接利用构造方法创建Bean对象。
每个对象被创建时都会调用构造方法,此时将这个方法单列出来是因为Spring还有许多绕着弯创建Bean对象的方法,后续会描述。
Bean 对象设置如下:
class User{ public User(){ System.out.println(“user构造方法被调用了”); }}
Spring配置文件如下:
<?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-4.3.xsd"> <bean name="user"class ="com.hello.spring.User"/></beans>
测试方法如下:
public class Main{ publicstatic void main(String []args){ //获取Spring容器 ApplicationContextcontext = newClassPathXmlApplicationContext("applicationContext.xml"); User user =(User)context.getBean("user"); }}
输出结果:
图1程序运行结果
(2)利用静态工厂的方法创建Bean对象
方法(1)是Spring直接利用构造方法创建Bean对象,这点从Spring的配置文件中也可以看出来,class属性直接是User类的权限定类型。利用静态工厂创建Spring的方法和上述方法较大不同,下面来看一下代码的组合以及Spring配置文件的改变。
Bean对象:
class Bean1{ publicBean1(){ System.out.println(“Bean1的方法被调用”) } public void say(){ System.out.println(“bean1say good afternoon”); }}
工厂类:
class BeanFactory{ publicstatic Bean1 getBean(){ System.out.println(“静态工厂方法被调用”) returnnew Bean1(); }}测试代码:
public class Main1{ publi cstatic void main(String []args){ ApplicationContextcontext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean1 bean1= (Bean1) context.getBean("bean1"); bean1.Say(); }}Spring的配置文件:
<bean name =”bean1” class=”Bean.BeanFactory”factory-method=”getBean”></bean>
测试结果:
图2 静态工厂运行结果
从上图的运行结果可以知道,利用这种方式配置Bean时,Spring并不是直接new Bean1(),而是借助工厂类的静态方法创建Bean对象的事例。
(3)利用实例工厂创建Bean对象
Bean对象:
class Bean1{ publicBean1(){ System.out.println(“Bean1的方法被调用”) } public void say(){ System.out.println(“bean1say good afternoon”); }}
工厂类:
class BeanFactory{ publicBeanFactory(){ System.out.println(“BeanFactory的构造方法被调用”) } publicstatic Bean1 getBean(){ System.out.println(“静态工厂方法被调用”) returnnew Bean1(); } publicBean1 getBeanByInstance(){ System.out.println(“实例方法创建Bean对象”); }}测试代码:
public class Main1{ publicstatic void main(String []args){ ApplicationContextcontext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean1 bean1= (Bean1) context.getBean("bean1"); bean1.Say(); }}
spring配置文件
<bean name =”factory” class=” Bean.BeanFactory”></bean><bean name=”bean1” factory-bean=”factory”factory-method=”getBeanByIntance”>
程序运行结果:
图3实例子工厂的运行结果
三丶Spring依赖注入的方式
Spring总共提供了四种依赖注入的方式,分别是基于xml的setter方式,基于xml的构造函数方式,基于注解的方式以及自动装配方式,在这四种装配方式中,使用得最多的方式是基于xml的setter方式以及基于注解的注入方式,这里重点介绍前三种装配方式。
(1)基于xml的setter方式注入
Bean对象:
class Student{ Friend friend; public Student(){ System.out.println(“student的构造方法被调用”); } public void say(){ System.out.println(“studentsay hello”); } public void setFriend(Friend friend){ System.out.println(“调用了set方法”); this. friend = friend; }}class Friend{ publicFriend(){ System.out.println(“friend的构造方法被调用”); }}
Spring配置文件:
<Bean name =”friend” class=”Bean.Friend”></Bean><Bean name =”stduent” class=”Bean.Student”> <propertyname =”friend” ref =”friend”></property></Bean>
测试类:
public class Main{ public static void main(String [] args){ ApplicationContext context= newClassPathXmlApplicationContext("applicationContext.xml"); Student student= (Student) context.getBean("student"); student.say(); }}
测试结果:
图4基于XML的set方法注入
观察上述的代码和执行结果,首先可以清晰看到这种方法的特点:被注入的属性必须设置set方法,在spring文件中对依赖属性需要配置property元素,其次可以发现Spring在注入的时候,先创建依赖对象,然后利用无参数构造方法创建Student对象,最后通过set方法将依赖对象friend注入到student对象中。
(2)基于xml的构造方法注入
//Bean对象:class Student{ Friend friend; public Student(Friend friend){ System.out.println(“student有参构造函数被调用”); this.friend = friend; } public Student(){ System.out.println(“student的构造方法被调用”); } public void say(){ System.out.println(“studentsay hello”); } public void setFriend(Friend friend){ System.out.println(“调用了set方法”); this. friend = friend; }}class Friend{ publicFriend(){ System.out.println(“friend的构造方法被调用”); }}
Spring配置文件:
<Bean name =”friend” class=”Bean.Friend”></Bean><Bean name =”stduent” class=”Bean.Student”> <constructor-arg index=”0” ref =”friend”/></Bean>
测试类:
public class Main{ public static void main(String [] args){ ApplicationContext context= newClassPathXmlApplicationContext("applicationContext.xml"); Student student= (Student) context.getBean("student"); student.say(); }}
测试结果:
图 5基于xml的构造函数注入方式
基于构造函数的注入方式的实现原理也很明显,在创建Student对象的时候,利用有参构造函数创建对象,完成属性注入,这种方式就是必须提供带参数的构造函数,spring的配置文件也要修改。
(3)基于注解的注入方式
上述介绍了两种基于xml的注入方式,这两种注入方式都十分的简单,但是当需要配置Bean对象十分对,且依赖关系十分复杂的时候,基于xml方式的注入方式将会使spring的配置文件十分臃肿,不利于后期维护,所以spring提供了一种基于注解的注入方式。
1.利用注解配置userControl对象
@Controller("userControl")public class UserControl { @Resource(name="userService") UserService userService; publicUserControl(){ System.out.println("UserControl的构造方法被调用了"); } publicvoid say(){ System.out.println("UserControl say hello"); }}
Controller声明了这个类交给Spring管理,并且暗示他在javaEE三层架构中处于Control层,Controller注解中的”userControl”相当于Spring配置文件中Bean的name属性。
2.利用注解配置userService对象
@Service("userService")public class UserService { @Resource(name="userDao") privateUserDao userDao; publicUserService(){ System.out.println("UserService构造方法被调用了"); }}
Service声明了这个类交给Spring管理,并且暗示他在javaEE三层架构中处于service层,Service注解中的”userService”相当于Spring配置文件中Bean的name属性。
3.利用注解配置userDao对象
@Repository("userDao")public class UserDao { publicUserDao(){ System.out.println("UserDao构造方法被调用"); }}
Repository声明了这个类交给Spring管理,并且暗示他在javaEE三层架构中处于Dao层,Repository注解中的”userDao”相当于Spring配置文件中Bean的name属性。
4.测试代码
public classMain3 { public staticvoid main(String [] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserControl userControl = (UserControl)context.getBean("userControl"); userControl.say(); }}
5.spring配置文件
<!—开启注解--> <context:annotation-config/> <!—扫描annotaation包下的所有Bean对象--><context:component-scanbase-package="annotation" />
6.测试结果
图6 基于注解的注入结果
利用注解配置Bean对象,可以极大的简化xml书写的工作量,但是其表达依赖关系的时候可能不是太直观。- 初见Sping之Bean
- SPING之bean作用域
- Sping之Bean的生命周期
- Sping bean的生命周期
- Sping Bean的装配
- sping bean 生命周期
- Sping中的Bean注入Servlet
- sping-装配Bean 基于XML
- Sping中的配置Bean详解
- 编码解析sping的bean原理
- Sping(一):Bean装配和注入
- Sping容器与被管的Bean
- Sping中Bean配置的深入探讨
- Groovy 我之初见
- Petshop 4.0 之初见
- symbian之初见
- 有感之博客初见
- Design Pattern之初见
- JAVASCRIPT学习笔记之正则表达式
- 工作中积累的一些mssql操作
- c# 内存机制
- fastjson反序列化
- [noip2006]2^k进制数(高精度+进制)
- 初见Sping之Bean
- 在不同的局域网内连接plsql显示无监听服务
- 如何使用Spring Boot从0到1搭建一个Java后台(一)
- 浅析WEB应用攻击及其防御方式
- 如何利用C++搭建个人专属的TensorFlow
- A Secure HDFS Client Example
- Unity3D 动态批量加载本地图片
- js判断中文字符和英文字符的长度
- img 图片高度设置为百分比无效的解答