前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架(二)反射机制, 注入, 单例模式, 自动装载, 延迟加载

Spring框架(二)反射机制, 注入, 单例模式, 自动装载, 延迟加载

作者头像
二十三年蝉
发布2018-02-28 11:11:02
1.6K0
发布2018-02-28 11:11:02
举报
文章被收录于专栏:闻道于事闻道于事闻道于事

 Spring反射机制:

1, 通过spring来获取一个对象的实例

1     <bean id="user" class="com.model.User">
2 
3     </bean>
1         ApplicationContext ac=new ClassPathXmlApplicationContext("Spring-all.xml");//调用此方法时类已经实例化好了
2         User u=(User)ac.getBean("user");//拿到实例化的类

2, 通过spring进行属性注入   setter方法注入

1     <!-- 通过Spring給类注入属性,通过空参构造方法 -->
2         <property name="username">
3             <value>hanqi</value>
4         </property>
5         <property name="password">
6             <value>123</value>
7         </property>   

  构造器注入

1         <!-- 
2         另一种通过带参构造方法-->
3         <constructor-arg index="0" value="name1"></constructor-arg>
4         <constructor-arg index="1" value="pwd1"></constructor-arg>     
5         

  接口注入

1 public class ClassA {  
2   private InterfaceB clzB;  
3   public init() {  
4   Ojbect obj =  
5   Class.forName(Config.BImplementation).newInstance();  
6   clzB = (InterfaceB)obj;  
7   }  
8   ……  
9   } 

  上面的代码中,ClassA依赖于InterfaceB的实现,如何获得InterfaceB实现类的实例?传统的方法是在代码中创建InterfaceB实现类的实例,并将起赋予clzB。

  而这样一来,ClassA在编译期即依赖于InterfaceB的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码,我们根据预先在配置文件中设定的实现类的类名,动态加载实现类,并通过InterfaceB强制转型后为ClassA所用。   这就是接口注入的一个最原始的雏形。   而对于一个Type1型IOC容器而言,加载接口实现并创建其实例的工作由容器完成,如J2EE开发中常用的Context.lookup(ServletContext.getXXX),都是Type1型IOC的表现形式。   Apache Avalon是一个典型的Type1型IOC容器。

  p标记的使用   <bean p:username=""></bean>

1     <bean id="user" class="com.model.User" p:username="pusername" p:password="ppwd">
2     </bean>

3, 将一个对象注入到另一个对象<ref bean="...">

用户有一个部门

部门有多个用户

model:

 1 package com.model;
 2 
 3 public class User {
 4     private String username;
 5     private String password;
 6     private Dept dept;
 7     
 8     
 9     public User() {
10         super();
11         // TODO Auto-generated constructor stub
12     }
13     public User(String username, String password, Dept dept) {
14         super();
15         this.username = username;
16         this.password = password;
17         this.dept = dept;
18     }
19     public String getUsername() {
20         return username;
21     }
22     public void setUsername(String username) {
23         this.username = username;
24     }
25     public String getPassword() {
26         return password;
27     }
28     public void setPassword(String password) {
29         this.password = password;
30     }
31     public Dept getDept() {
32         return dept;
33     }
34     public void setDept(Dept dept) {
35         this.dept = dept;
36     }
37     @Override
38     public String toString() {
39         return "User [username=" + username + ", password=" + password + ", dept=" + dept + "]";
40     }
41 
42     
43 }
 1 package com.model;
 2 
 3 import java.util.List;
 4 
 5 public class Dept {
 6     private int deptid;
 7     private String deptname;
 8     private List<User> users;
 9     
10     public Dept() {
11         super();
12         // TODO Auto-generated constructor stub
13     }
14     
15     public Dept(int deptid, String deptname, List<User> users) {
16         super();
17         this.deptid = deptid;
18         this.deptname = deptname;
19         this.users = users;
20     }
21 
22     public int getDeptid() {
23         return deptid;
24     }
25     public void setDeptid(int deptid) {
26         this.deptid = deptid;
27     }
28     public String getDeptname() {
29         return deptname;
30     }
31     public void setDeptname(String deptname) {
32         this.deptname = deptname;
33     }
34     
35     public List<User> getUsers() {
36         return users;
37     }
38 
39     public void setUsers(List<User> users) {
40         this.users = users;
41     }
42 
43     @Override
44     public String toString() {
45         return "Dept [deptid=" + deptid + ", deptname=" + deptname + ", users人数=" + users.size() + "]";
46     }
47 
48 }

配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:p="http://www.springframework.org/schema/p"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 
 7     <bean id="user1" class="com.model.User">
 8         <property name="username" value="苦海"></property>
 9         <property name="password" value="111"></property>
10         <property name="dept" ref="dept1"></property>
11 
12     </bean>
13     
14     <bean id="dept1" class="com.model.Dept">
15         <property name="deptid" value="6001"></property>
16         <property name="deptname" value="部门1"></property>
17         <property name="users">
18             <list>
19                 <ref bean="user1"/>
20             </list>
21         </property>
22     </bean>
23 
24 </beans>

测试:

 1 package com.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.model.Dept;
 7 import com.model.User;
 8 
 9 public class Test {
10     public static void main(String[] args) {
11         ApplicationContext ac=new ClassPathXmlApplicationContext("Spring-all.xml");//调用此方法时类已经实例化好了
12         
13         User u=(User)ac.getBean("user1");//拿到实例化的类
14         Dept d=(Dept)ac.getBean("dept1");
15         
16         System.out.println(u);
17         System.out.println(d);
18         ((ClassPathXmlApplicationContext)ac).close();
19         
20     }
21 }

4, AutoWired(byType, byName)

  autowire

自动装载:

byName根据名字自动注入

user1的bean中并没有dept属性,但是还是打印出了这个属性,因为它会找到这个类,然后在配置文件中找到和该属性同名的id,并自动注入

 1     <bean id="user1" class="com.model.User" autowire="byName">
 2         <property name="username" value="苦海"></property>
 3         <property name="password" value="111"></property>
 4     </bean>
 5     
 6     <bean id="dept" lazy-init="true" class="com.model.Dept" init-method="init" destroy-method="destory"  >
 7         <property name="deptid" value="6001"></property>
 8         <property name="deptname" value="部门1"></property>
 9         <property name="users">
10             <list>
11                 <ref bean="user1"/>
12             </list>
13         </property>
14     </bean>
1         ApplicationContext ac=new ClassPathXmlApplicationContext("Spring-all.xml");//调用此方法时类已经实例化好了
2         User u=(User)ac.getBean("user1");//拿到实例化的类
3         System.out.println(u);
4         ((ClassPathXmlApplicationContext)ac).close();

byType根据类型自动装载,用法一致

需要注意,如果根据类型自动装载,应只有一个该类型,否则会无发找到,报错

autowire默认default,指的是根据<beans>声明中得来选择方法

5, scope, lazy-init, init-method, destroy-method(相当的不重要)   scope="singleton(单例) / prototype(原型)"

默认情况下Spring中定义的Bean是以单例模式创建的。 在GoF中的单例模式是指一个ClassLoader中只存在类一个实例。 而在Spring中的单例实际上更确切的说应该是: 1.每个Spring Container中定义的Bean只存在一个实例 2.每个Bean定义只存在一个实例。

1     <bean id="user1" class="com.model.User" scope="singleton">
2         <property name="username" value="苦海"></property>
3         <property name="password" value="111"></property>
4     </bean>
1         ApplicationContext ac=new ClassPathXmlApplicationContext("Spring-all.xml");//调用此方法时类已经实例化好了    
2         User u=(User)ac.getBean("user1");//拿到实例化的类
3         User u2=(User)ac.getBean("user1");
4         System.out.println(u==u2);    
5         ((ClassPathXmlApplicationContext)ac).close();
1     <bean id="user1" class="com.model.User" scope="prototype">
2         <property name="username" value="苦海"></property>
3         <property name="password" value="111"></property>
4     </bean>
1         ApplicationContext ac=new ClassPathXmlApplicationContext("Spring-all.xml");
2         User u=(User)ac.getBean("user1");
3         User u2=(User)ac.getBean("user1");
4         System.out.println(u==u2);
5         ((ClassPathXmlApplicationContext)ac).close();

lazy-init="true" // 延迟加载,未生效

1 <bean id="dept1" lazy-init="true" class="com.model.Dept" init-method="init" destroy-method="destory"  >

 写在beans中,设置全局延迟加载

1     default-lazy-init="true"
lazy-init    (一开始不初始化,用到的时候才初始化)
    init-method="init" destory-method="destory"    不要和prototype一起使用
类被初始化的时候调用init,被消亡的时候调用destory

正常运行的结果只有一个init和destroy,虽然两个service实例化,但是默认是单例,加了scope=prototype就运行不正常了,结果两个init,没有destroy,原因未知。  首先我们应该知道: 一、spring Bean的作用域:scope=singleton(默认,单例,生成一个实例) 二、spring Bean的作用域:scope=prototype(多线程, 生成多个实例) 三、单例模式,默认在程序初始化的时候实例化(lazy-init=”false”) 四、prototype,getBean的时候才是实例化 五、lazy-init 只对单例模式起作用,对 prototype 不起作用(因为 prototype 默认就不是程序初始化的时候实例化的)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-09-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档