一、关于java单例设计模式
1、 含意
在某一个特定的环境,某一个类的类对象,永远只有一个
2、 分析
不是某一个工程,这个类对象只有一个
不是某个类只有一个,而是类的对象只有一个
3、 编程要点
1) 单例类
构造函数的作用域为private
不能在单例中检测是否单例
2) 分类
Ø 懒汉式
只有第1次请求时,才构建单例类
Ø 饿汉式
只有一遇到单例类,不一定是第1次请求时
遇到单例类可以类的静态属性,或方法的访问即可
4、 示例如下
public class Student_1 { static int n=1; private static Student_1 obj; //下面是静态代码块 static{ Log.getLog().info("这是一个静态块。。。"); } private Student_1() { Log.getLog().info("this="+this); } public static Student_1 getInstance(){ if(obj==null){ obj=new Student_1(); Log.getLog().info("单例对象构建完成,obj="+obj); } return obj; }
public int add(int a,int b){ Log.getLog().info("this="+this); return a+b; } //单例模式,不可以本类中main方法检测 public static void main(String[] args) { Student_1 o1=new Student_1(); Student_1 o2=new Student_1(); Student_1 o3=new Student_1(); Student_1 o4=new Student_1(); }
} |
public class Student_2 { static int n=2; private static Student_2 obj=new Student_2(); //下面是静态代码块 static{ Log.getLog().info("这是一个静态块。。。"); } private Student_2() { Log.getLog().info("this="+this); } public static Student_2 getInstance(){ return obj; }
public int add(int a,int b){ Log.getLog().info("this="+this); return a+b; } //单例模式,不可以本类中main方法检测 public static void main(String[] args) { Student_2 o1=new Student_2(); Student_2 o2=new Student_2(); Student_2 o3=new Student_2(); Student_2 o4=new Student_2(); }
} |
public class TestSingleton {
/** * @param args */ public static void main2(String[] args) { //构建类对象,不能直接new 类构造函数,因为作用域 // Student_1 obj=new Student_1(); Student_1 obj1= Student_1.getInstance(); //只能单例对象对外静态方法获取 Log.getLog().info("obj1="+obj1); Student_1 obj2= Student_1.getInstance(); //只能单例对象对外静态方法获取 Log.getLog().info("obj2="+obj2); boolean check=obj1==obj2; Log.getLog().info("check="+check);
} public static void main3(String[] args) { //构建类对象,不能直接new 类构造函数,因为作用域 Student_2 obj1= Student_2.getInstance(); //只能单例对象对外静态方法获取 Log.getLog().info("obj1="+obj1); Student_2 obj2= Student_2.getInstance(); //只能单例对象对外静态方法获取 Log.getLog().info("obj2="+obj2); boolean check=obj1==obj2; Log.getLog().info("check="+check);
}
//区别懒汉式与饿汉式单例的检测,在每个单例类中,加一个静态变量 public static void main(String[] args) { //构建类对象,不能直接new 类构造函数,因为作用域 Log.getLog().info("ok1?"); int n1=Student_1.n; Log.getLog().info("ok2?");
int n2=Student_2.n; Log.getLog().info("ok3?");
Student_1 obj1= Student_1.getInstance(); //只能单例对象对外静态方法获取 Log.getLog().info("ok4,obj1="+obj1);
Student_2 obj2= Student_2.getInstance(); //只能单例对象对外静态方法获取 Log.getLog().info("ok5,obj2="+obj2);
}
} |
二、 关于spring单例模式分析
1、 分析
spring只是借用单例的概念,这个类并不一定是真正的单例类
如果在spring容器中定义为单例类,则每一个ApplicationContext均会产生一个类对象
2、 示例如下
applicationCcontext.xml <bean class="com.iss.spring.UserPO"></bean>
</beans> |
public class UserPO { public UserPO() { Log.getLog().info("this="+this); }
} |
public class TestSpringSingleton {
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ac1=new ClassPathXmlApplicationContext("applicationContext.xml"); Log.getLog().info("ok?"); UserPO po1=ac1.getBean(UserPO.class); UserPO po2=ac1.getBean(UserPO.class); boolean check1=po1==po2; Log.getLog().info("check1="+check1);
ApplicationContext ac2=new ClassPathXmlApplicationContext("applicationContext.xml"); Log.getLog().info("ok2?"); UserPO po3=ac2.getBean(UserPO.class); UserPO po4=ac2.getBean(UserPO.class); boolean check2=po4==po3; Log.getLog().info("check2="+check2);
boolean check3=po1==po3; //false Log.getLog().info("check3="+check3);
}
} |
三、 关于spring数组bean注入
1、 实现需求
构建spring容器时,一次性加载N个xml容器配置文件,处理的效果,等效于同一个xml配置文件
2、 示例如下
public class User_1 { public User_1() { Log.getLog().info("this="+this); }
} public class User_2 { public User_2() { Log.getLog().info("this="+this); }
} public class User_3 { public User_3() { Log.getLog().info("this="+this); }
} |
bean1.xml <bean id="user1" class="com.iss.spring.array.User_1" scope="prototype"></bean> </beans> <bean id="user2" class="com.iss.spring.array.User_2" scope="prototype"></bean>
</beans> Bean3.xml <bean id="user3" class="com.iss.spring.array.User_3" scope="prototype"></bean>
</beans> |
Bean123.xml <bean id="user1" class="com.iss.spring.array.User_1" scope="prototype"></bean> <bean id="user2" class="com.iss.spring.array.User_2" scope="prototype"></bean> <bean id="user3" class="com.iss.spring.array.User_3" scope="prototype"></bean>
</beans> |
public class TestSpringArray {
/** * @param args */ public static void main2(String[] args) { // 采用数组方法构建spring容器 String[]beans={ "/com/iss/spring/array/Bean_1.xml", "/com/iss/spring/array/Bean_2.xml", "/com/iss/spring/array/Bean_3.xml" }; ApplicationContext ac=new ClassPathXmlApplicationContext(beans); Log.getLog().info("ok?"); //通过容器取得类对象 User_1 o1=ac.getBean(User_1.class); Log.getLog().info("o1="+o1); User_2 o2=ac.getBean(User_2.class); Log.getLog().info("o2="+o2); User_3 o3=ac.getBean(User_3.class); Log.getLog().info("o3="+o3);
} public static void main(String[] args) { // 采用数组方法构建spring容器 String[]beans={ "/com/iss/spring/array/Bean_123.xml" }; ApplicationContext ac=new ClassPathXmlApplicationContext(beans); Log.getLog().info("ok?"); //通过容器取得类对象 User_1 o1=ac.getBean(User_1.class); Log.getLog().info("o1="+o1); User_2 o2=ac.getBean(User_2.class); Log.getLog().info("o2="+o2); User_3 o3=ac.getBean(User_3.class); Log.getLog().info("o3="+o3);
}
} |
四、 关于spring另外一种方式构建容器
1、 实现需求
构建spring容器有多个方法
ApplicationContext是最常用的一种
BeanXmlFactory也是一种
还有注解方式
2、 问题分析
1) 一次性只能加载一个bean.xml配置文件,不能加载数组
2) 单例模式为懒汉式单例
3、 示例如下
public class TestSpringOther {
/** * @param args */ public static void main(String[] args) { // 采用其他方式构建 spring容器 Resource res=new ClassPathResource("/com/iss/spring/array/Bean_1.xml"); XmlBeanFactory xf=new XmlBeanFactory(res); Log.getLog().info("ok?"); //通过容器取得类对象 User_1 o1=xf.getBean(User_1.class); Log.getLog().info("o1="+o1); User_1 o2=xf.getBean(User_1.class); Log.getLog().info("o2="+o2); boolean check=o1==o2; Log.getLog().info("check="+check);
}
} |
五、 关于spring模块名称
1、 IOC模块
core模块
xmlbeanfactory模块
2、 aop模块
3、 jdbc模块,也称为DAO模块
4、 ORM模块
5、 WEB模块,也称为springmvc模块
6、 flow
7、 security
六、 关于spring集合类注入
1、 实现需求
注入List/Set/Map集合
2、 编程要点
1) 写一个类
2) 在类中加入集合类属性List/Set/Map各一个
3) 在Bean.xml中注册
List集合采用<list>标签,也可<set>标签
Set集合采用<set>标签,也可<list>标签
Map集合采用<entry key=... value=...>标签
4) 在spring容器中检测
3、 示例如下
public class UserSet { private List<String>list; private Set<String>set; private Map<Integer,String>map; public UserSet() { Log.getLog().info("this="+this); } public List<String> getList() { return list; } public void setList(List<String> list) { Log.getLog().info("list.size="+list.size()); for(int i=0;i<list.size();i++){ String value=list.get(i); Log.getLog().info(i+","+value); } this.list = list; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { Log.getLog().info("set.size="+set.size()); int i=0; for(String value:set){ // Log.getLog().info((i++)+","+value); Log.getLog().info(i+++","+value); //i,i++ } this.set = set; } public Map<Integer, String> getMap() { return map; } public void setMap(Map<Integer, String> map) { Log.getLog().info("map.size="+map.size()); Set<Integer>keys=map.keySet(); int i=0; for(Integer key:keys){ String value=map.get(key); Log.getLog().info(i+++","+key+","+value); } this.map = map; }
} |
Bean_set.xml <bean id="user" class="com.iss.spring.setdi.UserSet" scope="singleton"> <property name="list"> <list> <value>李晓华</value> <value>王海芳</value> <value>屈强东</value> <value>李晓华</value> </list> </property> <property name="set"> <set> <value>李晓华</value> <value>王海芳</value> <value>屈强东</value> <value>李晓华</value> </set> </property> <property name="map"> <map> <entry key="101" value="李晓华"/> <entry key="201" value="王海芳"/> <entry key="301" value="屈强东"/> <entry key="101" value="李晓芳"/> </map> </property> </bean>
</beans> |
public class TestSpringSetDI {
/** * @param args */ public static void main(String[] args) { //构建 spring工作容器 ApplicationContext ac=new ClassPathXmlApplicationContext("/com/iss/spring/setdi/Bean_set.xml"); Log.getLog().info("ok?"); //通过容器取得类对象 UserSet o=ac.getBean(UserSet.class); Log.getLog().info("o="+o); List<String>list=o.getList(); Log.getLog().info("list.size="+list.size()); for(int i=0;i<list.size();i++){ Log.getLog().info(i+","+list.get(i)); }
Set<String>set=o.getSet(); Log.getLog().info("\n\nset.size="+set.size()); Iterator<String>it=set.iterator(); for(int i=0;it.hasNext();i++){ String value=it.next(); Log.getLog().info(i+","+value); } Map<Integer,String>map=o.getMap(); Log.getLog().info("\n\nmap.size="+map.size()); Set<Integer>keys=map.keySet(); int i=0; for(Integer key:keys){ String value=map.get(key); Log.getLog().info(i+++","+key+","+value); }
}
} |
七、 关于[Bean.xml]文件
1、 是一个代名词
表示这是一个spring容器配置文件,不一定文件名称是Bean.xml,可能是任何其他文件名称
2、 可能是任何spring容器配置文件名称
八、 关于spring抽象类注入
1、 实现需求
spring的抽象类,不是真正的抽象类
这个类是一个不存在的假想的类
用于不同类之间注入时,共享类属性
2、 编程要点
1) 写2个不同的类
2) 2个类中有1个以上相同的类属性,便于共享类属性注入
3) 在spring的容器中抽象DI操作
注入2个类都有的类属性
这个bean是一个抽象类,abstract=”true”
4) 注册实际的类
并且每个类的父类是前面的抽象类
5) 在spring容器中检测
3、 示例如下
public class StudyA { private Integer studId; private String name; private String sex; private Date birthday; public StudyA() { Log.getLog().info("this="+this); } |
public class UserA { private String userId; private String name; private String sex; private Date birthday; |
BeanAbstract.xml <bean id="dt" class="java.util.Date" > <constructor-arg value="95"/> <constructor-arg value="5"/> <constructor-arg value="21"/> </bean> <bean id="comm" abstract="true" > <property name="name" value="王小波"/> <property name="sex" value="男"/> <property name="birthday" ref="dt"/> </bean> <bean class="com.iss.spring._abstract.UserA" parent="comm" scope="prototype"> <property name="userId" value='10088' /> </bean> <bean class="com.iss.spring._abstract.StudyA" parent="comm" scope="prototype"> <property name="studId" value='171004' /> </bean>
</beans> |
public class TestSpringAbstract {
/** * @param args */ public static void main(String[] args) { // 构建spring工作容器 ApplicationContext ac=new ClassPathXmlApplicationContext("com/iss/spring/_abstract/BeanAbstract.xml"); Log.getLog().info("ok?"); //通过容器取得类对象 StudyA s=ac.getBean(StudyA.class); Log.getLog().info("s="+s); Log.getLog().info( ","+s.getStudId()+ ","+s.getName()+ ","+s.getSex()+ ","+s.getBirthday().toLocaleString() );
UserA u=ac.getBean(UserA.class); Log.getLog().info("u="+u); Log.getLog().info( ","+u.getUserId()+ ","+u.getName()+ ","+u.getSex()+ ","+u.getBirthday().toLocaleString() );
}
} |
九、 关于工厂设计模式
1、 生活的工厂的特点
可以生产产品
这些产品是批量化生产
产品有可用性,可以卖给客户使用
2、 java的工厂
与生活的中工厂完全相同,有2个重要特点
如果一个类某个方法是工厂方法,则最少有2个特点
1) 生产产品功能,new 产品类();
2) 返回己生产的产品 return 产品类对象;
3、 java工厂设计模式要点
1) 写一个产品类
最少有一个属性,或方法,用于检测
2) 写一个工厂类
3) 在工厂类中工厂方法,通过工厂方法构建产品类对象
有静态工厂方法
有动态工厂方法
4) 在使用时,要依据工厂类,构建产品类对象
4、 示例如下
产品类 public class UserProduct { private Integer userId; private String name; private Date birthday; |
工厂类 public class UserFactory { public UserFactory() { Log.getLog().info("this="+this); } //静态工厂方法 public static UserProduct getInstance(){ Log.getLog().info("进入工厂。。。。"); //特点1,生产产品,必须有new 关键词 UserProduct u=new UserProduct(); //下面是对产品执行初始化操作 u.setName("王江东"); u.setUserId(10024); u.setBirthday(new Date(99,5,17)); //特点2,返回生产的产品 Log.getLog().info("工厂的工作己经完成,可以返回产品了。。。。,u="+u); return u;
} //动态工厂方法 public UserProduct getInstance2(){ Log.getLog().info("进入工厂。。。。"); //特点1,生产产品,必须有new 关键词 UserProduct u=new UserProduct(); //下面是对产品执行初始化操作 u.setName("王江东2"); u.setUserId(10022); u.setBirthday(new Date(99,5,12)); //特点2,返回生产的产品 Log.getLog().info("工厂的工作己经完成,可以返回产品了。。。。,u="+u); return u;
}
} |
如何使用工厂类造出来的产品 public class TestFactory {
/** * @param args */ public static void main2(String[] args) { // 采用工厂模式构建类对象 UserProduct obj=UserFactory.getInstance(); //不是直接new 出来的 Log.getLog().info("obj="+obj); Log.getLog().info( ""+obj.getUserId()+ ","+obj.getName()+ ","+obj.getBirthday().toLocaleString() ); } //检测动态工厂 public static void main(String[] args) { // 采用工厂模式构建类对象 UserFactory factory=new UserFactory(); Log.getLog().info("factory="+factory); UserProduct obj=factory.getInstance2(); //不是直接new 出来的 Log.getLog().info("obj="+obj); Log.getLog().info( ""+obj.getUserId()+ ","+obj.getName()+ ","+obj.getBirthday().toLocaleString() );
}
} |
十、 spring工厂模式用法
1、 编程要点
1) 要有产品类
2) 要有工厂类
3) spring的容器注册工厂
静态工厂注册,1个bean
动态工厂注册,2个bean
2、 示例如下
产品类,略 工厂类,略 |
BeanFactory.xml <!-- 静态工厂需要注册1个bean --> <bean id="obj1" class="com.iss.java.factory.UserFactory" factory-method="getInstance" scope="prototype"></bean> <!-- 动态工厂需要注册2个bean,第1个工厂bean,第2个是生产bean 动态工厂只能运行动态工厂方法,不能运行静态工厂方法 --> <bean id="factory" class="com.iss.java.factory.UserFactory" scope="prototype"></bean> <bean id="obj2" factory-bean="factory" factory-method="getInstance2" scope="prototype"></bean>
</beans> |
检测类 public class TestSpringFactory {
/** * @param args */ public static void main2(String[] args) { // 构建 spring工作容器 ApplicationContext ac=new ClassPathXmlApplicationContext("/com/iss/spring/factory/BeanFactory.xml"); Log.getLog().info("ok?"); //通过容器取得工厂类造出的产品对象 UserProduct obj=ac.getBean(UserProduct.class); Log.getLog().info("obj="+obj); Log.getLog().info( ","+obj.getUserId()+ ","+obj.getName()+ ","+obj.getBirthday(). );
} public static void main(String[] args) { // 构建 spring工作容器 ApplicationContext ac=new ClassPathXmlApplicationContext("/com/iss/spring/factory/BeanFactory.xml"); Log.getLog().info("ok?"); //通过容器取得工厂类造出的产品对象 UserProduct obj=ac.getBean("obj2",UserProduct.class); Log.getLog().info("obj="+obj); Log.getLog().info( ","+obj.getUserId()+ ","+obj.getName()+ ","+obj.getBirthday(). );
}
}
|