一:依赖注入
1.依赖注入—dependency injection
依赖:指bean对象创建依赖于容器。Bean对象的依赖资源
注入:指bean对象的依赖资源由容器来设置和装配。例:当一个对象构成属性是另一个对象时,那么spring就会自动装配那个对象。
2.spring注入—构造器注入
ioc通过构造器来创建对象
3.spring注入—setter注入
要求被注入的属性必须有set方法。Set方法的方法名由set+属性首字母大写。如果属性时Boolean没有get方法是is+属性名。
a)常量注入
<bean id="student" class="net.xyz.vo.Student">
<property name="name" value="张三丰"></property>
</bean>
b)Bean注入
<bean id="addr" class="net.xyz.vo.Address"></bean>
<bean id="student" class="net.xyz.vo.Student">
<property name="name" value="张三丰"></property>
<property name="addr" ref="addr"/>
</bean>
c)数组注入
<bean id="student" class="net.xyz.vo.Student">
<property name="name" value="张三丰"></property>
<property name="addr" ref="addr"/>
<property name="books" >
<array>
<value>三国演义</value>
<value>天龙八部</value>
<value>金瓶梅</value>
</array>
</property>
</bean>
d)List注入
<property name="hobbies">
<list>
<value>乒乓球</value>
<value>玻璃球</value>
<value>篮球</value>
<value>悠悠球</value>
</list>
</property>
d)Map注入
<property name="cards">
<map>
<entry key="中国银行" value="12345679"></entry>
<entry>
<key><value>建设银行</value></key>
<value>123546</value>
</entry>
</map>
</property>
e)Null注入
<property name="wife">
<null/>
</property>
f)properties注入
<property name="info">
<props>
<prop key="学号">201815121</prop>
<prop key="sex">男</prop>
<prop key="name">黄忠</prop>
</props>
</property>
g)p命名空间配置
配置文件:
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- p命名空间注入仍然需要set方法 -->
<bean id="user" class="net.xyz.vo.User" p:name="风清扬" p:age="123">
</bean>
f)c命名空间注入方法
配置头文件:
xmlns:c="http://www.springframework.org/schema/c"
<!-- c命名空间注入要求有对应的构造方法 -->
<bean id="user1" class="net.xyz.vo.User" c:name="josn" c:age="12"></bean>
二:Bean的作用域
- singleton 单例 整个容器中只有一个对象实例 ,没有scope的时候默认是单例
- prototype 原型 每次获取bean都产生一个新的对象
- request 每次请求时创建一个新的对象
- session 在会话的范围内时一个对象
- global session 只在portlet下有用,表示是application
- application 在应用范围中的一个对象
三:Bean的自动装配
Bean的自动装配–简化Spring的配置
<!-- autowire自动装配 简化Spring配置
no不适用自动装配
byName根据名称(set方法名来的)去查找相应的bean,如果有则装配上
byType根据类型自动装配,不用管bean的id,但是同一种类型的bean只能有一个
constructor 当通过构造器实例化bean时,使用byType的方式装配构造方法 -->
<bean id="service" class="net.xyz.service.impl.UserServiceImpl " autowire="byName">
</bean>
四:静态代理
1.静态代理的角色分析:
抽象角色—一般使用接口或者抽象类来实现。
真实角色—被代理的角色
代理角色—代理真实角色(代理真实角色后一般会做一些附属操作)
客户—使用代理角色来进行一些操作
例图:
2.代码实现
以客户租房为例,房东是真实角色,而中介要代理房东去租房,两个角色都实现了一个真实角色。
- Rent.java–抽象角色
public interface Rent {
public void rent();
}
- Host.java–真实角色
/**
* 房东
* @author lenovo
*
*/
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房屋出租");
}
}
- Proxy.java–代理角色
public class Proxy implements Rent {
private Host host;
public Proxy() {
}
public Proxy(Host host) {
super();
this.host = host;
}
public void setHost(Host host) {
this.host = host;
}
@Override
//租房
public void rent() {
seeHouse();
host.rent();
fare();
}
//看房
public void seeHouse() {
System.out.println("带房客看房");
}
//收取中介费
public void fare() {
System.out.println("收取中介费");
}
}
- Client.java–客户
/**
* 客户
* @author lenovo
*
*/
public class Client {
public static void main(String[] args) {
Host host=new Host();
Proxy proxy=new Proxy(host);
proxy.rent();
}
}
3.使用静态代理的好处:
使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情。
公共的业务由代理来完成—实现业务的分工
公共业务发生扩展时变得更加集中和方便
缺点:
类多了–多了代理类。工作量变大了。开发效率降低了
示例:UserService
抽象角色:
public interface UserService {
public void add();
public void update();
public void delete();
public void search();
}
代理角色:
public class UserServiceProxy implements UserService{
private UserService userService;
@Override
public void add() {
log("add");
userService.add();
}
@Override
public void update() {
// TODO Auto-generated method stub
log("update");
userService.update();
}
@Override
public void delete() {
// TODO Auto-generated method stub
log("delete");
userService.delete();
}
@Override
public void search() {
// TODO Auto-generated method stub
log("search");
userService.search();
}
public void log(String methodName) {
System.out.println("执行"+methodName+"方法");
}
}
客户:
public class UserServiceImpl implements UserService{
@Override
public void add() {
// TODO Auto-generated method stub
System.out.println("增加用户");
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("更新用户");
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("删除用户");
}
@Override
public void search() {
// TODO Auto-generated method stub
System.out.println("查找用户");
}
}
五:动态代理
- 动态代理和静态代理的角色是一样的。
- 动态代理的代理类是动态生成的。
- 分为两类一类基于接口动态代理和基于类的动态代理
a)基于接口动态代理—jdk动态代理
b)基于类的动态代理—cglib
现在javasist来生成动态代理。 - jdk动态代理—Proxy类和InvocationHandler接口
InvocationHandler是代理实例的调用处理程序实现的接口。每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,对方法掉一共进行编码并将其指派到它的调用处理程序的invoke方法。
示例:房东客户模型:
public class ProxyInovationHandler implements InvocationHandler{
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
/**
* 生成代理类
*/
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
Object result=method.invoke(rent,args);
fare();
return result;
}
//看房
public void seeHouse() {
System.out.println("带房客看房");
}
//收取中介费
public void fare() {
System.out.println("收取中介费");
}
}
public class Client {
public static void main(String[] args) {
Host host=new Host();
ProxyInovationHandler pih=new ProxyInovationHandler();
pih.setRent(host);
Rent proxy=(Rent) pih.getProxy();
proxy.rent();
}
}
UserService模型:
public class ProxyInovationHandler implements InvocationHandler{
private Object target;//代理类型
/**
* 生成代理类
*/
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result=method.invoke(target,args);
return result;
}
public void log(String messageName) {
System.out.println("调用"+messageName+"方法");
}
}
public class Client {
public static void main(String[] args) {
UserService userService=new UserServiceImpl();
ProxyInovationHandler pih=new ProxyInovationHandler();
pih.setTarget(userService);
UserService proxy= (UserService) pih.getProxy();
proxy.delete();
}
}