13, AOP
@1, 慎用继承 (因为继承直接就写死了!)
经常组合代替了继承,组合灵活性更高!
@2, Spring 解决了单例的问题
动态代理 jdk 如果想产生动态代理,那么这个类就需要实现一个接口,没有implements接口的类,JDK是给它产生不了动态代理的。
jdk proxy invocationhander
package com.bjsxt.aop;
LogInterceptor 很好!很好!写的!
package com.bjsxt.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LogInterceptor implements InvocationHandler {
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public void beforeMethod(Method m) {
System.out.println(m.getName() + " start");
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
beforeMethod(m);
m.invoke(target, args);
return null;
}
}
package com.bjsxt.dao;
interface UserDAO
package com.bjsxt.dao;
import com.bjsxt.model.User;
public interface UserDAO {
public void save(User user);
public void delete();
}
package
com.bjsxt.dao.impl;
UserDAOImpl
package com.bjsxt.dao.impl;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User;
public class UserDAOImpl implements UserDAO {
public void save(User user) {
//Hibernate
//JDBC
//XML
//NetWork
System.out.println("user saved!");
}
public void delete() {
System.out.println("user deteleted");
}
}
UserDAOImpl2
extends UserDAOImpl 继承的方式
package com.bjsxt.dao.impl;
import com.bjsxt.model.User;
public class UserDAOImpl2 extends UserDAOImpl {
@Override
public void save(User user) {
System.out.println("save start...");
super.save(user);
}
}
UserDAOImpl3 implements
UserDAO 实现接口的方式
package com.bjsxt.dao.impl;
import com.bjsxt.aop.LogInterceptor;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User;
public class UserDAOImpl3 implements UserDAO {
private UserDAO userDAO = new UserDAOImpl();
public void save(User user) {
new LogInterceptor().beforeMethod(null);
userDAO.save(user);
}
public void delete() {
// TODO Auto-generated method stub
}
}
package
com.bjsxt.model;
User (用户类 : 具有 名字 和 密码 两个属性)
package com.bjsxt.model;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.bjsxt.service;UserService 用户服务层
package com.bjsxt.service;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User;
public class UserService {
private UserDAO userDAO;
public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
packagecom.bjsxt.spring;
interface BeanFactory
package com.bjsxt.spring;
public interface BeanFactory {
public Object getBean(String id);
}
ClassPathXmlApplicationContext
package com.bjsxt.spring;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String , Object> beans = new HashMap<String, Object>();
//IOC Inverse of Control DI Dependency Injection
public ClassPathXmlApplicationContext() throws Exception {
SAXBuilder sb=new SAXBuilder();
Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //构造文档对象
Element root=doc.getRootElement(); //获取根元素HD
List list=root.getChildren("bean");//取名字为disk的所有元素
for(int i=0;i<list.size();i++){
Element element=(Element)list.get(i);
String id=element.getAttributeValue("id");
String clazz=element.getAttributeValue("class");
Object o = Class.forName(clazz).newInstance();
System.out.println(id);
System.out.println(clazz);
beans.put(id, o);
for(Element propertyElement : (List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name"); //userDAO
String bean = propertyElement.getAttributeValue("bean"); //u
Object beanObject = beans.get(bean);//UserDAOImpl instance
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println("method name = " + methodName);
Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
m.invoke(o, beanObject);
}
}
}
public Object getBean(String id) {
return beans.get(id);
}
}
beans.xml
<beans>
<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" >
</bean>
<bean id="userService" class="com.bjsxt.service.UserService" >
<property name="userDAO" bean="u"/>
</bean>
</beans>
Test 目录
package com.bjsxt.service;
package com.bjsxt.service;
import java.lang.reflect.Proxy;
import org.junit.Test;
import com.bjsxt.aop.LogInterceptor;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.dao.impl.UserDAOImpl;
import com.bjsxt.model.User;
import com.bjsxt.spring.BeanFactory;
import com.bjsxt.spring.ClassPathXmlApplicationContext;
public class UserServiceTest {
@Test
public void testAdd() throws Exception {
BeanFactory applicationContext = new ClassPathXmlApplicationContext();
UserService service = (UserService)applicationContext.getBean("userService");
User u = new User();
u.setUsername("zhangsan");
u.setPassword("zhangsan");
service.add(u);
}
@Test
public void testProxy() {
UserDAO userDAO = new UserDAOImpl();
LogInterceptor li = new LogInterceptor();
li.setTarget(userDAO);
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);
System.out.println(userDAOProxy.getClass());
userDAOProxy.delete();
userDAOProxy.save(new User());
}
/*class $Proxy4 implements UserDAO
* {
* save(User u) {
* Method m = UserDAO.getclass.getmethod
* li.invoke(this, m, u)
* }
* }
*/
}
14,
UserDAO userDAO = new UserDAOImpl();
LogInterceptor li = new LogInterceptor();
li.setTarget(userDAO);
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);
(1), 产生的代理对象的 classLoader 和 被代理对象的 classLoader 要一样,因为代理对象中有一个 被代理对象,所以需要互相访问。
(2), userDAO.getClass().getInterfaces() 代理类(对象) 要实现这个接口。
(3), 第三个参数,代理用哪一个 Handler 进行处理。
(4), 因为代理类实现了 UserDAO 接口,抽象主题,所以进行强制转换。(UserDAO)
System.out.println(userDAOProxy.getClass());
userDAOProxy.delete();
userDAOProxy.save(new User());
写程序推荐,面向接口编程。