Java框架之Spring(三)
本文主要介绍Spring中,
1 Bean 的 init-method 和 destroy-method
2 集合类型的装配
3 注解方式装配
4 以自动扫描把组件纳入spring容器中管理
5 代理模式
一、Bean 的 init-method 和 destroy-method
以前在学Servlet的时候,有 init 和 destory 等时机,用Spring管理的bean 也可以有类似的时机,对于单实例的Bean ,在创建的时候会调用 initAAA() 方法,在销毁的时候,会调用 destroyAAA()。
<bean name="userAction_name" class="cat.action.UserAction" init-method="initAAA" destroy-method="destroyAAA" >
public class UserAction {
public void initAAA(){
System.out.println("initAAA调用了,这是在初始的时候调用的");
}
public void destroyAAA(){
System.out.println("destroyAAA调用了,这是在销毁的时候调用的");
}
}
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml"); //会调用 initAAA()
ctx.getBean("userAction_name");
ctx.close(); //销毁容器 会调用destroyAAA()
//对于多实例的bean
<bean name="userAction_name" class="cat.action.UserAction" init-method="initAAA" destroy-method="destroyAAA" scope ="prototype" >
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
ctx.getBean("userAction_name"); //调用 initAAA()
ctx.close(); //销毁容器 不会会调用destroyAAA() //因为对多实例的bean spring 在创建之后,就不再对它的生命周期负责
二、集合类型的配置
1)Set集合
public class UserAction {
private Set<String> mySet ; //由Spring把这个集合的内容注进来
public void execute(){
for(String s:mySet){
System.out.println(s);
}
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
}
//配置文件
<bean name="userAction_name" class="cat.action.UserAction" >
<property name="mySet">
<set>
<value>李白</value>
<value>唐太宗</value>
<value>小杜</value>
</set>
</property>
2)List 集合
//和Set完全相同 只不过是上面的中的 set 要完全改成 list
<set>
<value>李白</value>
<value>唐太宗</value>
<value>小杜</value>
</set>
3) Properties 集合
public class UserAction {
private Properties myProps; //不要忘了生成set方法
public void execute(){
Set<String> keySet= myProps.stringPropertyNames();
Iterator<String> it=keySet.iterator();
while(it.hasNext()){
String key=it.next();
System.out.println(key+":"+myProps.getProperty(key));
}
}
...
}
<bean name="userAction_name" class="cat.action.UserAction" >
<property name="myProps">
<props>
<prop key="key1">夏天</prop>
<prop key="key2">秋天</prop>
<prop key="key3">冬天</prop>
<prop key="key4">春天</prop>
</props>
</property>
</bean>
4) map集合
public class UserAction {
private Map<String,String> myMap; //要生成set 方法
public void execute(){
Set<Map.Entry<String, String>> entrySet = myMap.entrySet();
Iterator<Map.Entry<String, String>> it= entrySet.iterator();
while(it.hasNext()){
Map.Entry<String, String > item= it.next();
System.out.println(item.getKey()+":"+item.getValue());
}
}
<bean name="userAction_name" class="cat.action.UserAction" >
<property name="myMap">
<map>
<entry key="m_1" value="AK-47"></entry>
<entry key="m_2" value="M_16"></entry>
<entry key="m_3" value="M_P5"></entry>
</map>
</property>
</bean>
三、注解方式装配
附 : p 这个名称空间的作用就是简化属性的编写
<bean name="userInfo" class="cat.beans.UserInfo" >
<property name="id" value="1"></property>
<property name="userName" value="赵强"></property>
<property name="password" value="admin"></property>
<property name="note" value="这是备注"></property>
</bean>
上面的等价于:
<bean name="userInfo" class="cat.beans.UserInfo"
p:id="1"
p:userName="赵强"
p:note="这是备注"
p:password="admin123"
>
</bean>
1) 引入jar包 common-annotations.jar
2) 引用入名称空间 context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" //这是引入的名称空间
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
//上面这个是名称空间所对应的xsd文件的路径 <context:annotation-config /> //把Spring 对注解的处理器注册到Spring中
<bean name="userAction_name" class="cat.action.UserAction" />
<bean name="userDao_name" class="cat.dao.UserDaoImpl" />
</beans>
public class UserAction {
@Resource //用这个注解,进行注入
private IUserDao dao;
public void execute(){
dao.addUser();
dao.updateUser();
}
}
说明:
1.@Resource 是 javax.annotation.Resource 包下的
2.@Resource 默认是按名称进行装配,再按类型进行装配(在不指定名称的情况下),如果指定了名称.它就严格的按名称进行装配
3.这个注解也可以写在set方法上
//下面的例子,使用了名称
public class UserAction {
@Resource(name="xxxxxx_dao")
private IUserDao dao; public void execute(){
dao.addUser();
dao.updateUser();
}
}
<bean name="userAction_name" class="cat.action.UserAction" />
<bean name="xxxxxx_dao" class="cat.dao.UserDaoImpl" /> //它会被注入
<bean name="oracleDao" class="cat.dao.UserDaoOracleImpl" />
4.@Autowired 注解和 @Resource 功能类似,它是在 org.springframework.beans.factory.annotation.Autowired 默认是按类型装配 ,默认情况下,它要求依赖对象必须存在 ,如果对象是null 值 ,可以设置它的 required=false ,如果也想按名称装配 ,要和另一个注解一起使用
//例子 使用 @Autowired
public class UserAction {
@Autowired(required=false) @Qualifier("oracleDao")
private IUserDao dao; //没有给它生成get 和 set 方法 public void execute(){
dao.addUser();
dao.updateUser();
}
}
四、以自动扫描把组件纳入spring容器中管理
开启自动扫描的方式
<context:component-scan base-package="cat.beans" />
<context:component-scan base-package="cat.dao" /> //如果用这种方式开启了自动扫描,就不用加
<context:annotation-config />
它会自动在包下查找类 并纳入Spring管理,包扩子包。它会自动找 带有 @Service @Controller @Repository @Component 的类
==@Service 用于业务层
==@Controller 用于控制层
==@Repository 用于数据访问层
==@Component 用于其他
目前只是一种规范,实际上用哪个都可以
说明:
1) 可以指定bean的名称
@Controller("userAction_name") //传参,指定名称
public class UserAction {
...
}
2) 默认情况下,这样配置的bean是单例的,如果是多例
@Controller("userAction_name") @Scope("prototype")
public class UserAction {
}
//例子 控制层
@Controller("userAction_name") @Scope("prototype")
public class UserAction { @Resource(name="userDaoOracleImpl")
private IUserDao dao; public void execute(){
dao.addUser();
dao.delUser();
}
} //数据访问层
@Repository
public class UserDaoOracleImpl implements IUserDao {
public void addUser() {
System.out.println("addUser方法被调用了Oracle版的 ");
}
public void delUser() {
System.out.println("delUser方法被调用了Oracle版的 ");
} public void updateUser() {
System.out.println("updateUser方法被调用了Oracle版的 ");
}
} //测试
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
UserAction action =(UserAction) ctx.getBean("userAction_name");
action.execute(); //对于纳入自动扫描的bean ,它的名称默认是类名, 首字母小写
注意:使用了注解方式以后,原来的初始化和销毁方法应该怎么配置呢?
@Component @Scope("prototype")
public class UserAction { ...
@PostConstruct //初始方法
public void initAAA(){
System.out.println("初始化的方法被调用了");
}
@PreDestroy //销毁方法
public void destoryAAA(){
System.out.println("销毁的方法被调用了");
}
五、代理模式
因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗?
你有想过限制访问某个对象,也就是说,提供一组方法给普通用户, 特别方法给管理员用户?以上两种需求都非常类似,并且都需要解决一个更大的问题:你如何提供一致的接口给某个对象让它可以改变其内部功能,或者是从来不存在的功能? 可以通过引入一个新的对象,来实现对真实对象的操作或者将新的对象作为真实对象的一个替身。即代理对象。它可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点
静态代理
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前,就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
//1) 接口
public interface IUserDao {
void addUser();
void delUser();
void updateUser();
void searchUser();
} //2) 实现类 //委托类
public class UserDaoImpl implements IUserDao{
public void addUser() {
System.out.println("addUser方法执行了");
} public void delUser() {
System.out.println("delUser方法执行了");
} public void updateUser() {
System.out.println("updateUser方法执行了");
} public void searchUser() {
System.out.println("searchUser方法执行了");
}
}
//3) 代理类
public class UserDaoProxy implements IUserDao {
private UserDaoImpl userDaoImpl=new UserDaoImpl(); //代理类中,要有一个被委托的类的实例对象
private String path="log.txt"; public void addUser() {
try {
userDaoImpl.addUser();
BufferedWriter bw=new BufferedWriter(new FileWriter(path));
bw.write(new Date()+": 执行了添加用户操作 ");
bw.newLine();
bw.close(); } catch (IOException e) {
e.printStackTrace();
}
} public void delUser() {
try {
userDaoImpl.delUser();
BufferedWriter bw=new BufferedWriter(new FileWriter(path));
bw.write(new Date()+": 执行了删除用户操作 ");
bw.newLine();
bw.close(); } catch (IOException e) {
e.printStackTrace();
}
} public void updateUser() {
try {
userDaoImpl.updateUser();
BufferedWriter bw=new BufferedWriter(new FileWriter(path));
bw.write(new Date()+": 执行了更新用户操作 ");
bw.newLine();
bw.close(); } catch (IOException e) {
e.printStackTrace();
}
} public void searchUser() {
long begin=System.currentTimeMillis();
userDaoImpl.searchUser();
long end=System.currentTimeMillis(); System.out.println("查询用户一共用了:" +(end-begin) +"ms");
} }
//3) 代理工厂
public class static UserDaoProxyFactory {
public IUserDao getUserDao(){
return new UserDaoProxy();
}
}
//4) 测试
public static void main(String[] args) {
IUserDao dao=UserDaoProxyFactory.getUserDao();
dao.addUser();
dao.updateUser();
dao.delUser();
dao.searchUser();
}
静态代理的缺点:
1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
Java框架之Spring(三)的更多相关文章
- java框架之Spring(2)-注解配置IOC&AOP配置
注解配置IoC 准备 1.要使用注解方式配置 IoC,除了之前引入的基础 jar 包,还需要引入 spring-aop 支持包,如下: 2.在 applicationContext.xml 中引入 c ...
- java框架篇---spring AOP 实现原理
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- Java框架之Spring(四)
本文主要讲述在Spring中 1 注解方式装配 2 以自动扫描把组件纳入spring容器中管理 3 面象切面编程-代理的jdk 版实现 4 使用 Cglib 生成代理 5 aop编程的一些概念 6 使 ...
- Java - 框架之 Spring
一. IOC 和 DI IOC : 控制反转,将对象的创建权反转给了 Spring.DI : 依赖注入,前提是必须要有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入(设置)进来 ...
- java框架篇---spring hibernate整合
在会使用hibernate 和spring框架后 两个框架的整合就变的相当容易了, 为什么要整合Hibernate?1.使用Spring的IOC功能管理SessionFactory对象 LocalSe ...
- java框架篇---spring aop两种配置方式
第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步: 1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Befor ...
- java框架篇---spring IOC 实现原理
IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用 ...
- Java框架之Spring MVC(二)
一.Spring MVC 验证 JSR 303 是ajvaEE6 中的一项子规范 ,叫 Bean Validation 用于对javaBean中的字段进行校验. 官方的参考实现是: Hibernate ...
- Java框架之Spring MVC(一)
一.Spring简介 Spring MVC是当前最优秀的 MVC 框架,自从Spring 2.5 版本发布后,由于支持注解配置,易用性有了大幅度的提高.Spring 3.0 更加完善,实现了对 Str ...
随机推荐
- 第39章:MongoDB-集群--Replica Sets(副本集)---副本集基本原理
①操作日志oplog Oplog是主节点的local数据库中的一个固定集合,按顺序记录了主节点的每一次写操作,MongoDB的复制功能是使用oplog来实现的,备份节点通过查询这个集合就可以知道需要进 ...
- JavaScript基础视频教程总结(021-030章)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Html5与Css3知识点拾遗(八)
css5新增的元素与属性 表单内元素的属性 1. form属性 之前必须书写在表单内部.而在Html5中,可以放在任何位置,为元素指定一个form属性,属性值为该表单的id,就可以声明该元素属于指定表 ...
- 过滤器和拦截器filter和Interceptor的区别
1.创建一个Filter过滤器只需两个步骤 创建Filter处理类 web.xml文件中配置Filter 2.Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的 ...
- noip第23课资料
- freeRTOSConfig.h文件对FreeRTOS进行系统配置
FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制.每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核.这个配置文件是针 ...
- React-Native 问题随记2: com.android.builder.testing.api.DeviceException
错误详细: Execution failed for task ':app:installDebug'.> com.android.builder.testing.api.DeviceExcep ...
- JavaScript中JSON对象和JSON字符串的相互转化
一.JSON字符串转换为JSON对象 var str = '{"name":"cxh","sex":"man",&quo ...
- Mybatis框架三:DAO层开发、Mapper动态代理开发
这里是最基本的搭建:http://www.cnblogs.com/xuyiqing/p/8600888.html 接下来做到了简单的增删改查:http://www.cnblogs.com/xuyiqi ...
- Python语法基础——关于全局变量与局部变量
1.函数内部的变量名如果第一次出现,且出现在=前面,即被视为定义一个局部变量,不管全局域中有没有用到该变量名,函数中使用的将是局部变量,例如: num = 100 def func(): num = ...