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 ...
随机推荐
- 根据word模板dotx文件创建word
doc = this._wordApplication.Documents.Add(@"D:\Fdsfsdsfsdfds.dotx"); 用这个会把模板的样式,文字内容都创建到新w ...
- mybatis环境配置与入门例子
1.jar包的导入 mybatis需要jar包:mybatis-3.4.6.jar mysql驱动jar包:mysql-connector-java-5.1.34.-bin.jar 日志记录jar包: ...
- Scala微服务架构 三
四 Controller层 之前我们已经把基层架构搭建好了,那么要如何使用呢? 首先看看我的Controller层代码 @Singleton class BMAuthController @Injec ...
- python 中numpy中函数hstack用法和作用
定义: Stack arrays in sequence horizontally (column wise). Take a sequence of arrays and stack them ho ...
- Python Web Service
搞移动端有段时间了,一直使用别人的API,自己也只写过ASP.NET网站作为网络服务,相对来讲是很大的短板.虽然ASP.NET可以提供想要的web服务,但是其体量臃肿,响应速度非常慢,这点我非常不喜欢 ...
- 1ink 与 @import 的区别
1ink与@import的区别 目录 1ink与@import的区别 差别1:归属关系的差别 差别2:加载顺序的差别 差别3:兼容性的差别 差别4:使用dom控制样式时的差别 1ink与@import ...
- [Umbraco] umbraco中如何分页
分页功能应该说是web开发中最基本的功能了,常规的做法是通过查询sql语句进行分页数据显示.但在umbraco中却不是这样子的.而且通过xpath中的postion来定位.如下代码 <?xml ...
- vue父子组件传递参数之props
vue中父组件通过props传递数据给子组件, props有两种传递方式 1.props:['msg']2.props: { msg:{ type:String, default:"&quo ...
- Eclipse markers窗口使用
项目提示有错误,又不知道错误是哪里导致的,这时你可以打开eclipse的markers窗口查看错误信息或者警告信息 markers窗口提示信息: 到项目工程目录的settings目录下找到org.ec ...
- 又拍云 Node.js 实现文件上传、删除
Node.js 服务端 使用 Node.js + Express.js 实现 服务端 const express = require("express"); const app = ...