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. linux 相关零碎知识整理

    1.启动bash shell 大部分linux系统启动用户命令行接口(cli)环境时使用默认的bash shell,在bash shell启动时,它将自动执行位于用户主目录下的.bashrc中的命令. ...

  2. day 23 复习

    本来应该学习day23,由于上午未学习,下去困,导致今天未进行进度 那就做一下简单的复习吧! 1. while else结构,如果while 后的条件条件不再满足 引发循环再继续,则执行else中的内 ...

  3. day 19 os模块的补充 序列化 json pickle

    os   模块 os.path.abspath  规范绝对路径 os.path.split() 把路径分成两段,第二段是一个文件或者是文件夹 os.path.dirname    取第一部分 os.p ...

  4. 【记录】洛谷P1739-表达式括号匹配AC记

    题面请查看:https://www.luogu.org/problem/P1739 思路: 见到括号就搜索,搜到与它配对的括号为止,搜不到就输出NO 代码: #include <bits/std ...

  5. c# 为什么会出现死锁?多线程死锁怎么解决

    出现死锁必须满足以下几个条件: 1.互斥条件:该进程拥有的资源,其他进程只能等待其释放. 2.不剥夺条件:该进程拥有的资源只能由它自己来释放. 3.请求和保持条件:请求其他的资源,同时自己拥有的资源又 ...

  6. Android Saripaar 注解详解

    写这篇文章的原因 在移动端一般很少使用复杂的表单,一般针对于属性的更改都会打开一个新的页面进行更改.虽然不多,但是也会有.如果一个页面要输入的内容包括姓名.地址.邮箱.手机号等,对各个属性的验证会非常 ...

  7. MySQL-简介-安装(5.5版和5.7版)

    1.什么是MySQL (1)MySQL是一种关联数据库管理系统. (2)关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库中,可以增加速度,提高灵活性. (3)MySQL使用的是数据库常 ...

  8. javaSE笔记(重点部分)

    Java 基础篇 数据类型 基本数据类型 由于java是强类型语言,所以要进行有些运算的时候,需要用到类型转换. 低-----------------------------高 byte,short, ...

  9. C#——Unity事件监听器

    事件监听器 事件类型 public enum BaseHEventType { GAME_OVER, GAME_WIN, PAUSE, ENERGY_EMEPTy, GAME_DATA } 事件基类 ...

  10. mysql的安装及命令

    1.先检查系统是否装有mysql rpm -qa | grep mysql 2.下载mysql的repo源 wget     http://192.168.130.150/mysql5.7.26/my ...