IOC概念解析
ioc简单代码示例
IMessage.java
public interface IMessage {
public abstract String getMessage();
}
Message.java
public class Message implements IMessage {
@Override
public String getMessage() {
return "Hello World!";
}
}
NewMessage.java
public class NewMessage implements IMessage {
@Override
public String getMessage() {
return "Hello Every One!";
}
}
message.properties
1=com.alyshen.spring.Message
2=com.alyshen.spring.NewMessage
MessageFactory.java
public class MessageFactory {
public static IMessage create(String key) {
// if ("1".equals(key)) {
// //工厂还是依赖这个类
// return new Message();
// }
//
// 使用资源文件
ResourceBundle bundle = ResourceBundle.getBundle("message");
String _class = bundle.getString(key);
try {
return (IMessage) Class.forName(_class).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
MainClass.java
public class MainClass {
public static void main(String[] args) {
// 这个类强依赖Message这个类
// Message msg = new Message();
// 我们不想看到Message这个具体的产品
// IMessage msg = new Message();
IMessage msg = MessageFactory.create("1");
System.out.println(msg.getMessage());
msg = MessageFactory.create("2");
System.out.println(msg.getMessage());
}
}
Spring环境配置及IOC工厂应用
用到的包以及文件
包以文件 | 说明 |
---|---|
applicationContext.xml | Spring配置文件 |
spring-context-3.2.0.M1.jar | 主要提供bean工厂的实现类,工厂就在里头,但是接口在spring-beans-3.2.0.M1.jar里头 |
spring-beans-3.2.0.M1.jar | bean工厂在里头 |
spring-core-3.2.0.M1.jar | Spring核心包 |
spring-expression-3.2.0.M1.jar | 支持spring表达式的 |
spring-asm-3.2.0.M1.jar | 动态生成一些类的(动态生成字节码的类) |
commons-logging-1.1.1.jar | 依赖包(公共日志包) |
spring配置文件:applicationContext.xml
使用spring的bean工厂
public class MainClass {
public static void main(String[] args) {
// 使用spring 的bean工厂
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 使用通配符
// BeanFactory factory = new ClassPathXmlApplicationContext("app*.xml");
IMessage msg = (IMessage) factory.getBean("msg1");
System.out.println(msg.getMessage());
// 我们自己的bean工厂
msg = MessageFactory.create("2");
System.out.println(msg.getMessage());
}
}
Spring依赖注入的基本方法
set方法注入示例
UserManager.java
public class UserManager {
// 依赖set方法注入
private String driverCalss;
private String url;
private String username;
private String password;
public void addUser() {
System.out.println(this.toString());
System.out.println("用户管理_添加用户!");
}
public void setDriverCalss(String driverCalss) {
this.driverCalss = driverCalss;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "UserManager [driverCalss=" + driverCalss + ", url=" + url
+ ", username=" + username + ", password=" + password + "]";
}
}
UserAction.java
public class UserAction {
private UserManager manager = null;
public void setManager(UserManager manager) {
System.out.println("调用属性manager的set方法注入!");
this.manager = manager;
}
public String execute() {
this.manager.addUser();
return "success";
}
}
spring配置文件:applicationContext.xml
MainClass.java
public static void main(String[] args) {
// 使用spring 的bean工厂
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// BeanFactory factory = new ClassPathXmlApplicationContext("app*.xml");
UserAction ua = (UserAction) factory.getBean("userAction");
System.out.println(ua.execute());
}
Scope属性和BeanFactoryAware接口
UserManager.java
public class UserManager {
// 依赖set方法注入
private String driverCalss;
private String url;
private String username;
private String password;
public void addUser() {
System.out.println("用户管理_添加用户!");
}
//各种set及get方法
……
}
UserAction.java
/**
* 实现接口BeanFactoryAware
*/
public class UserAction implements BeanFactoryAware {
private UserManager manager = null;
public void setManager(UserManager manager) {
// System.out.println("调用属性manager的set方法注入!");
this.manager = manager;
}
public String execute() {
// 每次调用这方法都重新创建bean工厂耗费资源,丧失性能
// BeanFactory factory =
// new ClassPathXmlApplicationContext("applicationcontext.xml");
// 非要实现单列对象注入多例对象属性实现:
// 重新为属性赋值
manager = (UserManager) factory.getBean("userManager");
System.out.println(manager);
this.manager.addUser();
return "success";
}
BeanFactory factory = null;
@Override
public void setBeanFactory(BeanFactory factory) throws BeansException {
// TODO Auto-generated method stub
this.factory = factory;
}
}
applicationContext.xml
MainClass.java
public static void main(String[] args) {
// UserAction userAction = new UserAction();
// UserManager manager = new UserManager();
// userAction.setManager(manager);
// 使用spring 的bean工厂
// BeanFactory factory = new ClassPathXmlApplicationContext("app*.xml");
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationcontext.xml");
UserAction ua = (UserAction) factory.getBean("userAction");
System.out.println(ua);
System.out.println(ua.execute());
ua = (UserAction) factory.getBean("userAction");
System.out.println(ua);
System.out.println(ua.execute());
ua = (UserAction) factory.getBean("userAction");
System.out.println(ua);
System.out.println(ua.execute());
}
id_name_ref(bean、local、parent)等属性的用法
applicationContext.xml
MainClass.java
/**
* BeanFactory factory = new
* ClassPathXmlApplicationContext("applicationContext02.xml");
*
* 将factory作为父工厂(已不使用)
* BeanFactory fay = new XmlBeanFactory( newClassPathResource(
* "applicationContext.xml"), factory );
*/
set方法注入集合属性
UserAction.java
public class UserAction {
public List list = null;
public Set set = null;
public Map map = null;
public Properties props = null;
public void setList(List list) {
this.list = list;
}
public void setSet(Set set) {
this.set = set;
}
public void setMap(Map map) {
this.map = map;
}
public void setProps(Properties props) {
this.props = props;
}
}
applicationContext.xml
dfdsf
155.54
1115
true
jdbc.mysql.Driver
root
654321
jdbc:mysql://localhost:3306/mydb
- MainClass.java
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
UserAction userAction = (UserAction) factory.getBean("userAction");
System.out.println("---------------list------------");
for (Object o : userAction.list) {
System.out.println(o);
}
System.out.println("---------------set------------");
for (Object o : userAction.set) {
System.out.println(o);
}
System.out.println("----------------map-----------");
for (Iterator iter = userAction.map.entrySet().iterator(); iter
.hasNext();) {
System.out.println(iter.next());
}
for (Object key : userAction.map.keySet()) {
System.out.println(key + ":" + userAction.map.get(key));
}
System.out.println("--------------props-------------");
Properties prop = userAction.props;
System.out.println(prop.get("driverClass"));
System.out.println(prop.get("username"));
System.out.println(prop.get("password"));
System.out.println(prop.get("url"));
}
构造注入及注意事项
- A.java
public class A {
private int id;
private String username;
private String password;
private char sex;
private Date birthday;
@Override
public String toString() {
return "A [id=" + id + ", username=" + username + ", password="
+ password + ", sex=" + sex + ", birthday=" + birthday + "]";
}
public A(int id, String username, String password, char sex, Date birthday) {
super();
this.id = id;
this.username = username;
this.password = password;
this.sex = sex;
this.birthday = birthday;
}
//各种set、get方法
……
}
- applicationContext.xml
- MainClass.java
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
A a = (A) factory.getBean("a");
System.out.println(a.toString());
}
- 注意事项
a) A.java
public class A {
private B b;
public void setB(B b) {
this.b = b;
}
/**
* 参数构造器
*/
public A(B b) {
super();
this.b = b;
}
/**
* 默认构造器
*/
public A() {
super();
}
}
b) B.java
public class B {
private A a;
public void setA(A a) {
this.a = a;
}
public B(A a) {
super();
this.a = a;
}
public B() {
super();
}
}
c) applicationContext.xml
自动注入及注意事项
- UserManager.java
public class UserManager {
public void addUser() {
System.out.println("添加用户!");
}
}
- UserAction.java
public class UserAction {
private UserManager manager = null;
/**
* 参数构造器注入
*/
public UserAction(UserManager manager) {
super();
this.manager = manager;
}
/**
* set方法注入
*/
public void setManager(UserManager manager) {
System.out.println("调用manager的set方法注入!");
this.manager = manager;
}
public String execute() {
System.out.println(manager);
manager.addUser();
return "success";
}
}
- applicationContext.xml
- MainClass.java
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserAction ua = (UserAction) factory.getBean("userAction");
System.out.println(ua);
System.out.println(ua.execute());
}
通过注解注入
- applicationContext.xml
- UserAction.java
public class UserAction {
@Resource
private UserManager manager = null;
//Set方法都省了
// @Resource
// public void setManager(UserManager manager) {
// System.out.println("调用manager的set方法注入!");
// this.manager = manager;
// }
public String execute() {
System.out.println(manager);
this.manager.addUser();
return "success";
}
}
Spring自动扫描组件
- applicationContext.xml
- UserManager.java
@Repository("uManager")
public class UserManager {
public void addUser() {
System.out.println("用户管理执行添加User对象的操作!");
}
}
- UserService.java
@Service("uService")
public class UserService {
@Resource(name = "uManager")
private UserManager manager;
public void service() {
System.out.println("调用Service");
manager.addUser();
}
}
- UserAction.java
@Controller("uAction")
//@Scope("prototype") //多例
public class UserAction {
@Resource(name = "uService")
private UserService service;
public String execute() {
System.out.println("调用Action");
service.service();
return "success";
}
}
- MainClass.java
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// UserAction ua = (UserAction) factory.getBean("userAction");
UserAction ua = (UserAction) factory.getBean("uAction");
System.out.println(ua);
ua = (UserAction) factory.getBean("uAction");
System.out.println(ua);
ua = (UserAction) factory.getBean("uAction");
System.out.println(ua);
System.out.println(ua.execute());
}
关注点分离和静态代理
- 关注点分离
Me.java
@Component
public class Me {
@Resource
private Servant servant;
public void dowork() {
makeBeds();// 关注点
dress();// 关注点
haveAMeal();// 关注点
System.out.println("我工作……");// 真正的业务
haveAMeal();// 关注点
makeBeds();// 关注点
undress();// 关注点
}
// 使用面向过程编程
private void makeBeds() {
System.out.println("叠被子");
}
private void dress() {
System.out.println("穿衣服");
}
private void haveAMeal() {
System.out.println("吃饭");
}
private void undress() {
System.out.println("脱衣服");
}
}
- 静态代理
a) MeInterface.java
public interface MeInterface {
public abstract void dowork();
}
b) Me.java
@Component("me")
public class Me implements MeInterface {
@Override
public void dowork() {
System.out.println("我工作……");// 真正的业务
}
}
c) Servant.java
@Component("ser")
public class Servant {
public void work1() {
this.makeBeds();
this.dress();
this.haveAMeal();
}
public void work2() {
this.haveAMeal();
this.puChuang();
this.undress();
}
public void makeBeds() {
System.out.println("叠被子");
}
public void dress() {
System.out.println("穿衣服");
}
public void haveAMeal() {
System.out.println("吃饭");
}
public void undress() {
System.out.println("脱衣服");
}
public void puChuang() {
System.out.println("铺床");
}
}
d) MyProxy.java
@Component
public class MyProxy implements MeInterface {
@Resource(name = "me")
private Me target;// 真正的目标对象,我们这个代理服务的对象
@Resource(name="ser")
private Servant servant;
@Override
public void dowork() {
servant.work1();
target.dowork();
servant.work2();
}
}
e) 使用代理
@Test
public void test() {
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MeInterface me = (MeInterface) factory.getBean(MyProxy.class);
//代理将我的关注点做好再让我去工作……
me.dowork();
}
动态代理和横切关注点分离
- DynamicProxyFactory.java
public class DynamicProxyFactory implements InvocationHandler {
private DynamicProxyFactory() {
}
// 自己new的没法注入,通过创建代理的newInstance方法注入
private Servant servant;
private Object target;
/**
* 创建代理的静态方法
*/
public static Object newInstance(Object target, Servant servant) {
DynamicProxyFactory dp = new DynamicProxyFactory();
dp.servant = servant;
dp.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), dp);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
servant.work1();
Object o = // 调用动态代理类代理的目标对象上的方法(真正要调用的业务方法)
method.invoke(target, args);
servant.work2();
return o;
}
}
- applicationContext.xml
- 使用动态代理
@Test
public void test() {
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MeInterface me = (MeInterface) factory.getBean("my");
//代理将我的关注点做好再让我去工作……
me.dowork();
System.out.println("--------------------");
HeInterface he = (HeInterface) factory.getBean("h");
he.hedowork();
}
利用Spring的AspectJ创建动态代理分离横切关注点
- 用到的包
aspectjrt.jar Spring的依赖包
aspectjweaver.jar Spring的依赖包
aopalliance.jar aop
spring-aop-3.2.0.M1.jar aop支持类
- applicationContext.xml
- AspClass.java
/**
* 切面类
*/
@Aspect
@Component
public class AspClass {
@Resource(name = "ser")
private Servant servant;
@Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
void before() {
servant.work1();
}
@After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
void after() {
servant.work2();
}
}
- 使用Spring的AspectJ创建的动态代理
@Test
public void test() {
BeanFactory factory = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MeInterface me = (MeInterface) factory.getBean("me");
//代理将我的关注点做好再让我去工作……
me.dowork();
System.out.println("--------------------");
HeInterface he = (HeInterface) factory.getBean("he");
he.hedowork();
}
- 可以不使用切面类AspClass
a) Servant01
@Aspect
@Component
public class Servant01 implements Ordered {
@Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
public void makeBeds() {
System.out.println("叠被子");
}
@Override
public int getOrder() {
return 0;
}
}
b) Servant02
@Aspect
@Component
public class Servant02 implements Ordered{
@Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
public void dress() {
System.out.println("穿衣服");
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 1;
}
}
c) Servant03
@Aspect
@Component
public class Servant03 implements Ordered {
@Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
public void haveAMeal() {
System.out.println("吃饭");
}
@After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
public void haveAMeal2() {
System.out.println("吃饭");
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 2;
}
}
d) Servant04
@Aspect
@Component
public class Servant04 implements Ordered{
@After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
public void puChuang() {
System.out.println("铺床");
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 1;
}
}
e) Servant05
@Aspect
@Component
public class Servant05 implements Ordered{
@After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
public void undress() {
System.out.println("脱衣服");
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return 0;
}
}
- Around、AfterThrowing等其它Advice
a) Me.java
@Component("me") public class Me implements MeInterface { @Override public void dowork() { if (true) throw new RuntimeException("RuntimeException……"); System.out.println("我工作……");// 真正的业务 } }
b) AspClass.java
/**
* 切面类
*/
@Aspect
@Component
public class AspClass {
@Resource(name = "ser")
private Servant servant;
/**
* @param 执行方法的东西
* @return 返回方法的返回值
*/
// @Around("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
// public Object test(ProceedingJoinPoint proceeding) {
// Object o = null;
// try {
// servant.work1();
// // proceeding.proceed(proceeding.getArgs());
// o = proceeding.proceed();
//
// servant.work2();
// } catch (Throwable e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// return o;
// }
@Before("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
void before() {
System.out.println("开始代理……");
servant.work1();
}
@After("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
void after() {
servant.work2();
System.out.println("结束代理……");
}
/**
* 返回时执行(最后执行)
*/
@AfterReturning("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
void test2() {
System.out.println("返回……");
}
/**
* 抛异常 注意:不能跟定义了@Around的方法连着用,否则不执行
*/
@AfterThrowing("execution(* com.ashmit.spring.MeInterface.*(..))||execution(* com.ashmit.spring.HeInterface.*(..))")
void test3() {
System.out.println("抛异常……");
}
}
Spring配置文件中配置切面
- AspClass.java
/**
* 切面类
*/
@Component("aspclass")
public class AspClass {
@Resource(name = "ser")
private Servant servant;
void before() {
servant.work1();
}
void after() {
servant.work2();
}
}
- applicationContext.xml
Spring AOP声明式事务
- 用到的包
commons-dbcp.jar
commons-pool.jar
spring-jdbc-3.2.0.M1.jar 以上dataSource需要
spring-orm-3.2.0.M1.jar sessionFactory需要
spring-aop-3.2.0.M1.jar aop支持类
spring-tx-3.2.0.M1.jar 事物通知
- applicationContext.xml
com.ashmit.entity.User
com.ashmit.entity.Group
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hbm2ddl.auto=update
javax.persistence.validation.mode=none
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
- 事务传播特性
Spring与Struts框架的集成
- 用到的包
struts2-spring-plugin-2.3.4.jar 在Struts文件中
spring-web-3.2.0.M1.jar 在Spring文件中
- UserAction.java
@Controller("userAction")
public class UserAction implements ModelDriven {
private User user = null;
@Resource(name = "groupService")
private GroupService groupService = null;
@Resource(name = "userService")
private UserService userService = null;
//各种方法
……
}
- web.xml
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml
……
BaseDao模式
- BaseDao.java
public class BaseDao {
@Resource(name = "sessionFactory")
private SessionFactory sessionFactory = null;
protected Session getSession() {
return this.sessionFactory.getCurrentSession();
}
}
OpenSessionInView模式
应对懒加载策略
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml
OpenSessionInViewFilter
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
OpenSessionInViewFilter
/*
……