Spring简介

Spring不是服务于开发web项目的功能,或业务。而是服务于项目的开发,方便各层间的解耦调用,方便对类的批量管理,是提高软件开发效率,降低后期维护成本的框架。
Spring的核心思想是IOC(控制反转),AOP(切面编程)两点。
IOC:即不再需要程序员去显式地`new`一个对象,而是把Spring框架把框架创建出的对象拿来用。因为是spring框架创建的对象,对象都在spring框架对象中保存,亦称为spring容器,这样spring就知道当前项目中都创建了哪些对象,这个对象归属于那一层,该如何管理。想使用spring的其他功能第一点就是要用spring的对象,也称为将控制权交给spring管理。
AOP:对某种路径下的所有类,或有共同特性的类或方法统一管理,在原任务执行的前后,加入新功能。做出监控,初始化,整理,销毁等一系列统一的伴随动作。
如果你从事Java编程有一段时间了, 那么你或许会发现(可能你也实际使用过) 很多框架通过强迫应用继承它们的类或实现它们的接口从而导致应用与框架绑死。这种侵入式的编程方式在早期版本的Struts以及无数其他的Java规范和框架中都能看到。Spring竭力避免因自身的API而弄乱你的应用代码。Spring不会强迫你实现Spring规范的接口或继承Spring规范的类,相反,在基于Spring构建的应用中,它的类通常没有任何痕迹表明你使用了Spring。 最坏的场景是, 一个类或许会使用Spring注解, 但它依旧是POJO。
任何一个有实际意义的应用(肯定比Hello World示例更复杂) 都会由两个或者更多的类组成, 这些类相互之间进行协作来完成特定的业务逻辑。 按照传统的做法, 每个对象负责管理与自己相互协作的对象(即它所依赖的对象) 的引用, 这将会导致高度耦合和难以测试的代码。

IOC声明Bean

首先创建的Maven Poject,详细包结构如下

其中AOP会在下一篇进行讲解;

Controller_.java

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("/ApplicationContext.xml");
Service_ s = (Service_) ctx.getBean("service_Impl1_new");
System.out.println(s);
s.show();
}

由于Spring无法单独演示,所以Controller_.java是创建的是一个Servlet,直接调用doPost或者doGet方法,进行Service的实现,输出Service_对象s,执行show方法。

Service_.java

public interface Service_ {
public void show();
}

创建一个Service接口,用来实现Spring。

1.无参构造方法声明bean

Service_Impl1.java

public class Service_Impl1 implements Service_{

    public Service_Impl1() {
// TODO Auto-generated constructor stub
System.out.println("service1-无参构造方法");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl1");
} }

重写Service_的show方法输出实现了Service_Impl1,编写无参构造方法。

ApplicationContext.xml

<!-- 默认构造方法 -->
<bean id="service_Impl1" class="com.zy.spring.service.serviceimpl.Service_Impl1"></bean>

只需要设置id与class,class对应Service_Impl1,id则是Controller_.java调用的getBean中的参数。运行结果见自定义构造方法注入bean

2.自定义构造方法声明bean

Service_Impl2.java

public class Service_Impl2 implements Service_{

    public Service_Impl2(int a) {
// TODO Auto-generated constructor stub
System.out.println("service2-自定义构造参数:"+a);
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl2");
} }

ApplicationContext.xml

 <!-- 自定义构造方法 -->
<bean id="service_Impl2" class="com.zy.spring.service.serviceimpl.Service_Impl2">
<constructor-arg index="0" value="1024"></constructor-arg>
</bean>

<constructor-arg index="0" value="1024"></constructor-arg>这是构造方法中参数的设置,index顾名思义就是索引的意思,其中a参数是第0个,value是参数的值。

3.单实例 懒加载声明bean

Service_Impl3.java

public class Service_Impl3 implements Service_{
public Service_Impl3() {
// TODO Auto-generated constructor stub
System.out.println("service3-懒加载 单实例");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl3");
} }

ApplicationContext.xml

 <!--  单实例 懒加载 -->
<bean id="service_Impl3" class="com.zy.spring.service.serviceimpl.Service_Impl3" lazy-init="true" scope="singleton"></bean>

lazy-init="true" 设置懒加载,也就是调用的时候才会加载bean,不会自动加载;scope="singleton" 作用域标签,单实例也就是只创建一个实例。

4.参数引用声明bean

Service_Impl4.java

public class Service_Impl4 implements Service_{

    Service_ s3;

    public Service_ getS3() {
return s3;
}
public void setS3(Service_ s3) {
this.s3 = s3;
}
public Service_Impl4() {
// TODO Auto-generated constructor stub
System.out.println("service4-参数引用bean");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl4");
} }

ApplicationContext.xml

<!-- 参数引用bean -->
<bean id="service_Impl4" class="com.zy.spring.service.serviceimpl.Service_Impl4">
<property name="s3" ref="service_Impl3"></property>
</bean>

<property name="s3" ref="service_Impl3"></property> 参数标签,name是Service_Impl4中的参数s3,ref链接要引用的bean。

5.初始化属性声明bean

Service_Impl5.java

public class Service_Impl5 implements Service_{
String name;
ArrayList<String> list;
HashMap<String, String> map;
HashSet<Integer> set; @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((list == null) ? 0 : list.hashCode());
result = prime * result + ((map == null) ? 0 : map.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((set == null) ? 0 : set.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Service_Impl5 other = (Service_Impl5) obj;
if (list == null) {
if (other.list != null)
return false;
} else if (!list.equals(other.list))
return false;
if (map == null) {
if (other.map != null)
return false;
} else if (!map.equals(other.map))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (set == null) {
if (other.set != null)
return false;
} else if (!set.equals(other.set))
return false;
return true;
}
@Override
public String toString() {
return "Service_Impl5 [name=" + name + ", list=" + list + ", map=" + map + ", set=" + set + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<String> getList() {
return list;
}
public void setList(ArrayList<String> list) {
this.list = list;
}
public HashMap<String, String> getMap() {
return map;
}
public void setMap(HashMap<String, String> map) {
this.map = map;
}
public HashSet<Integer> getSet() {
return set;
}
public void setSet(HashSet<Integer> set) {
this.set = set;
} public Service_Impl5() {
// TODO Auto-generated constructor stub
System.out.println("service5-初始化属性");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl5");
} }

其中初始化参数有list,map,set以及普通参数,重写了hashCode和equals方法,详见HashMap内存泄漏;重写toString方法用来输出初始化属性。

ApplicationContext.xml

<!--     初始化属性  -->
<bean id="service_Impl5" class="com.zy.spring.service.serviceimpl.Service_Impl5">
<property name="name" value="zy"></property>
<property name="map">
<map>
<entry key="AAA" value="aaa"></entry>
<entry key="BBB" value="bbb"></entry>
</map>
</property> <property name="list">
<list>
<value type="java.lang.String">QQQ</value>
<value type="java.lang.String">WWW</value>
</list>
</property> <property name="set">
<set>
<value type="java.lang.Integer">111</value>
<value type="java.lang.Integer">222</value>
</set>
</property>
</bean>

其中map标签内使用<entry key="AAA" value="aaa"></entry>进行赋值。其他的正常使用property和value进行赋值。

6.初始化属性引用方法返回值声明bean

Service_Impl6.java

public class Service_Impl6 implements Service_{
String s5_toString; public String getS5_toString() {
return s5_toString;
}
public void setS5_toString(String s5_toString) {
this.s5_toString = s5_toString;
} public Service_Impl6() {
// TODO Auto-generated constructor stub
System.out.println("service6-调用方法返回值");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl6 返回值"+s5_toString);
} }

其中调用了Service_Impl5的toString方法并且进行了输出。

ApplicationContext.xml

<!--     调用方法返回值 -->
<bean id="service_Impl6" class="com.zy.spring.service.serviceimpl.Service_Impl6">
<property name="s5_toString">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="service_Impl5"></property>
<property name="targetMethod" value="toString"></property>
</bean>
</property>
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">固定用来声明调用方法返回值。

targetObject——目标的bean

targetMethod——目标的方法

7.静态工厂——声明工厂bean

Service_Impl7.java

public class Service_Impl7 implements Service_{

    public static Service_ StaticFactory(int num) {
switch (num) {
case 1:
return new Service_Impl1();
case 2:
return new Service_Impl2(100);
case 3:
return new Service_Impl3();
case 4:
return new Service_Impl4();
case 5:
return new Service_Impl5();
default:
return new Service_Impl6();
}
} public Service_Impl7() {
// TODO Auto-generated constructor stub
System.out.println("service7-静态工厂");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl7");
} }

工厂在实现类中使用了switch语句进行模拟,静态工厂在方法前加上static关键字,分别调用上面的其他实现类方法。

ApplicationContext.xml

<!--   静态工厂 -->
<bean id="service_Impl7" class="com.zy.spring.service.serviceimpl.Service_Impl7" factory-method="StaticFactory" >
<constructor-arg name="num" value="2"></constructor-arg>
</bean>

使用构造方法注入的方法来赋值<constructor-arg name="num" value="2"></constructor-arg> ;factory-method="StaticFactory" ( factory-method工厂的方法名)

8.实例工厂——声明工厂bean

Service_Impl8.java

public class Service_Impl8 implements Service_{

    public  Service_ factory1(int num) {
switch (num) {
case 1:
return new Service_Impl1();
case 2:
return new Service_Impl2(100);
case 3:
return new Service_Impl3();
case 4:
return new Service_Impl4();
case 5:
return new Service_Impl5();
default:
return new Service_Impl6();
}
} public Service_Impl8() {
// TODO Auto-generated constructor stub
System.out.println("service8-实例工厂");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl8");
} }

ApplicationContext.xml

  <!-- 实例工厂 -->
<bean id="service_Impl8" class="com.zy.spring.service.serviceimpl.Service_Impl8" >
</bean>
<bean id="service_Impl8_new" factory-bean="service_Impl8" factory-method="factory1">
<constructor-arg name="num" value="2"></constructor-arg>
</bean>

创建实例工厂bean,首先创建一个实例工厂的bean,然后再创建一个工厂方法的bean去调用工厂的bean。

调用的时候要调用工厂方法的bean,这里就要调用service_Impl8_new

9.注解声明bean

@Service:用于标注业务层组件
@Controller:用于标注控制层组件(如struts中的action)
@Repository:用于标注数据访问组件,即DAO组件
@Component(value="*"):泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注

Service_Impl9.java

@Service
public class Service_Impl9 implements Service_{ public Service_Impl9() {
// TODO Auto-generated constructor stub
System.out.println("service9-注解注入bean");
}
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("Service_Impl9");
} }

@Service进行bean的声明(注解只能声明无参构造方法),使用注解默认声明的bean是类名的首字母小写,这里声明的bean的id应该是service_Impl9。

ApplicationContext.xml

 <!-- 注解扫描IOC根目录 -->
<context:component-scan base-package="com.zy.spring">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!-- 扫描不包括controller -->
</context:component-scan>

使用注解需要加上注解扫描,其中base-package是扫描的目录,一般使用的是项目的根目录,以后使用SpringMVC的话,就不用扫描Controller。

注解写入bean

@Resource(name="*" type="*")bean写入
@Autowired/@Qualifier
@inject/@named

Spring基础——IOC九种bean声明方式的更多相关文章

  1. spring IOC容器实例化Bean的方式与RequestContextListener应用

    spring IOC容器实例化Bean的方式有: singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在. prototype 每次从容器中调用Bean时, ...

  2. 框架源码系列九:依赖注入DI、三种Bean配置方式的注册和实例化过程

    一.依赖注入DI 学习目标1)搞清楚构造参数依赖注入的过程及类2)搞清楚注解方式的属性依赖注入在哪里完成的.学习思路1)思考我们手写时是如何做的2)读 spring 源码对比看它的实现3)Spring ...

  3. 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程

    原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ...

  4. javascript中var let const三种变量声明方式

    javascript中var let const三种变量声明方式 1.var  ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...

  5. JS的两种函数声明方式的区别

    ---恢复内容开始--- js中常见的两种函数声明方式如下: // 函数表达式 var f = function() { console.log(1); } // 直接声明 function f () ...

  6. Spring基础[IOC/DI、AOP]

    一.Spring作用:管理项目中各种业务Bean(service类.Dao类.Action类),实例化类,属性赋值 二.Spring IOC(Inversion of Control )控制反转,也被 ...

  7. Spring基础知识之装配Bean

    装配(wiring):创建应用对象之间协作关系的行为.这是依赖注入的本质. Spring配置的可选方案 Spring提供了三种装配机智: 1)在XML中进行显示装配 2)在java中进行显示装配 3) ...

  8. 死磕Spring之IoC篇 - 开启 Bean 的加载

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  9. 【死磕 Spring】—– IOC 之解析Bean:解析 import 标签

    原文出自:http://cmsblogs.com 在博客[死磕Spring]----- IOC 之 注册 BeanDefinition中分析到,Spring 中有两种解析 Bean 的方式.如果根节点 ...

随机推荐

  1. Spring项目中优雅的异常处理

    前言 如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Co ...

  2. Linux发展史及安装

    操作系统 什么是操作系统 人与硬件的中介/桥梁 操作系统的组成  操作系统可以理解为一个鸡蛋 蛋黄    内核                   Linux内核  托瓦斯  鸡蛋清  命令解释器(s ...

  3. easywechat微信开发SDK之小微商户进件(二)

    正式开始进件之前需要准备几个东西 1.服务商商户号 2.API密钥 微信服务商后台中设置 3.APIv3密钥 微信服务商后台中设置 4.API证书路径  登录服务商后台下载  生成证书官方又文档的 很 ...

  4. Mac卸载mysql并安装mysql升级到8.0.13版本

    引言 今天mysql升级到8.0.13版本,遇到了很多问题,在此进行总结方便以后查看. 卸载mysql brew uninstall mysql sudo rm /usr/local/mysql su ...

  5. 【数据结构】之栈(C语言描述)

    栈(Stack)是编程中最常用的数据结构之一. 栈的特点是“后进先出”,就像堆积木一样,堆的时候要一块一块堆到最上面,拆的时候需要从最上面一块一块往下拆.栈的原理也一样,只不过它的操作不叫堆和拆,而是 ...

  6. 【Android - 组件】之Activity生命周期的全面分析

    Activity是Android四大组件之首,其重要性不言而喻,Activity的生命周期更是我们了解Android工作机制的重中之重.我们一般将Activty的生命周期做两种情况下的理解,即正常情况 ...

  7. Nginx安装、默认虚拟主机、Nginx用户认证和域名重定向

    6月7日任务 12.6 Nginx安装12.7 默认虚拟主机12.8 Nginx用户认证12.9 Nginx域名重定向 扩展nginx.conf 配置详解 http://www.ha97.com/51 ...

  8. 如何使用pandas分析金融数据

    [摘要]pandas是数据分析师分析数据最常用的三方库之一,结合matplotlib,非常强大. 首先我们收集一些数据. 从东方财富客户端导出券商信托板块2018年11月1日的基础行情和财务数据.分别 ...

  9. 华为云ROMA,联接企业应用的现在与未来

    2019.9.19日,在华为全联接大会的华为云Summit中,华为云CTO宇昕总提出:"企业的应用与数据集成,始终是数字化转型和智能化升级的关键,华为云企业应用与数据集成平台ROMA,打破时 ...

  10. 安装破解版IntelliJ IDEA

    1.下载IntelliJ IDEA http://www.jetbrains.com/idea/download/#section=windows 选择Ultimate版本 2.注册码破解 http: ...