一:依賴注入
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();
}
}