IOC
构造方法注入示例:
Client.java
package com.java.client;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.java.manager.UserManager;
public class Client {
public static void main(String[] args) {
// UserManager userManager = new UserManagerImpl(new UserDaoMysql());
// userManager.addUser("张三", "123");
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.addUser("小三", "怎么的");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
<bean id="userDaoMysql" class="com.java.dao.UserDaoMysql"></bean>
<bean id="userDaoOracle" class="com.java.dao.UserDaoOracle"></bean>
<bean id="userManager" class="com.java.manager.UserManagerImpl">
<constructor-arg ref="userDaoOracle"/>
</bean>
</beans>
UserManager.java
public interface UserManager {
public void addUser(String usernmae,String password);
}
UserManagerImpl.java
public class UserManagerImpl implements UserManager {
private UserDao userDao;
//构造方法赋值
public UserManagerImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void addUser(String username, String password) {
//之前由我们自己负责对象
//UserDao userDao = new UserDaoMysql();
userDao.addUser(username, password);
}
}
UserDao.java
public interface UserDao {
public void addUser(String username,String password);
}
UserDaoMysqlImpl.java
public class UserDaoMysql implements UserDao {
@Override
public void addUser(String username, String password) {
System.out.println("-----------Mysql已存储-----------");
}
}
UserDaoOracleImpl.java
public class UserDaoOracle implements UserDao {
@Override
public void addUser(String username, String password) {
System.out.println("----------Oracle已存储-----------");
}
}
构造方法注入与set方法注入区别:
public class UserManagerImpl implements UserManager {
private UserDao userDao;
@Override
public void addUser(String username, String password) {
userDao.addUser(username, password);
}
//set方法注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
applicationContext.xml
<bean id="userDaoMysql" class="com.java.dao.UserDaoMysql"></bean>
<bean id="userDaoOracle" class="com.java.dao.UserDaoOracle"></bean>
<bean id="userManager" class="com.java.manager.UserManagerImpl">
<property name="userDao" ref="userDaoMysql"/>
</bean>
构造方法注入:
UserManagerImpl.java
public class UserManagerImpl implements UserManager {
private UserDao userDao;
//构造方法赋值
public UserManagerImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void addUser(String username, String password) {
userDao.addUser(username, password);
}
}
applicationContext.xml
<bean id="userDaoMysql" class="com.java.dao.UserDaoMysql"></bean>
<bean id="userDaoOracle" class="com.java.dao.UserDaoOracle"></bean>
<bean id="userManager" class="com.java.manager.UserManagerImpl">
<constructor-arg ref="userDaoOracle"/>
</bean>
属性注入:
Bean1.javapackage com.java;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Bean1 {
private String strValue;
private int intValue;
private List listValue;
private Set setValue;
private String[] arrayValue;
private Map mapValue;
// 此处省略 Setter Getter 方法
// …………
}
applicationContext.xml
<bean id="bean1" class="com.java.Bean1">
<property name="strValue" value="小龙_你好"></property>
<property name="intValue" value="88888"></property>
<property name="listValue">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<property name="setValue">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="arrayValue">
<list>
<value>array1</value>
<value>array2</value>
</list>
</property>
<property name="mapValue">
<map>
<entry key="k1" value="v1"></entry>
<entry key="k2" value="v2"></entry>
</map>
</property>
</bean>
日期格式注入 属性编辑器
Test.javapublic class Test {
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Bean1 bean1 = (Bean1)factory.getBean("bean1");
System.out.println(bean1.getDate());
}
}
Bean1.java
public class Bean1 {
private Date date;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
UtilDateEditor.java
package com.java;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
//Date属性编辑器
public class UtilDateEditor extends PropertyEditorSupport{
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("----------属性编辑器---------");
try {
//配置格式
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(text);
//注入属性
this.setValue(date);
} catch (ParseException e) {
e.printStackTrace();
throw new IllegalArgumentException("日期参数非法");
}
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
<bean id="customEditors" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="com.java.UtilDateEditor"></bean>
</entry>
</map>
</property>
</bean>
<bean id="bean1" class="com.java.Bean1">
<property name="date" value="2014-10-01"></property>
</bean>
</beans>
减少配置量_将公共配置抽象
<bean id="parentBean" abstract="true">
<property name="id" value="100"></property>
<property name="name" value="大龙"></property>
<property name="sex" value="男"></property>
</bean>
<bean id="bean4" class="com.java.Bean4" parent="parentBean">
<property name="age" value="18"></property>
</bean>
AOP
- Cross Cutting Concern
— 是一种独立服务,他会遍布在系统的处理流程之中
- Aspect
— 对横切性关注点的模块化
- Advice
— 对横切关注点的具体实现
- Pointcut
— 他定义了Advice应用到哪些JoinPiont(方法)上,对Spring来说是方法调用
- Weave
— 将Advice应用到Target Object上的过程叫织入,Spring支持的是动态织入
- Target Object
— Advice被应用的对象
- Proxy
— Spring AOP默认使用JDK的动态代理,它的代理是运行时创建,也可以使用CGLIB代理
- Introduction
— 可以动态的为类添加方法
AOP示例(采用Annotation方式)
Demo.java
package com.java;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.addUser("张三", "root");
}
}
UserManager.java
package com.java;
public interface UserManager {
public void addUser(String username,String password);
public void delUser(int id);
public String findUser(int id);
public void modifyUser(int id,String username,String password);
}
UserManagerImpl.java
package com.java;
public class UserManagerImpl implements UserManager {
@Override
public void addUser(String username, String password) {
System.out.println("添加用户成功");
}
@Override
public void delUser(int id) {
System.out.println("删除用户成功");
}
@Override
public String findUser(int id) {
System.out.println("查找用户成功");
return "知道我是谁吗";
}
@Override
public void modifyUser(int id, String username, String password) {
System.out.println("修改用户成功");
}
}
Check.java
package com.java;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class Check {
/**
* 该方法无意义,标识作用(类似id)
*/
@Pointcut("execution(* add*(..))")
private void addAddMethod(){}
/**
* 定义Advice,表示我们的Advice应用到
* 哪些Pointcut订阅的Joinpoint上
*/
@Before("addAddMethod()")
private void check(){
System.out.println("例行检查");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 启用AspectJ对Annotation的支持 -->
<aop:aspectj-autoproxy/>
<bean id="userManager" class="com.java.UserManagerImpl222"></bean>
<bean id="check" class="com.java.Check"></bean>
</beans>
AOP示例(采用配置文件方式)
Check.javapackage com.java;
public class Check {
private void check(){
System.out.println("例行检查");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="userManager" class="com.java.UserManagerImpl222"></bean>
<bean id="check" class="com.java.Check"></bean>
<aop:config>
<aop:aspect id="checkAspect" ref="check">
<aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
<aop:after method="check" pointcut-ref="addAddMethod"/>
</aop:aspect>
</aop:config>
</beans>
AOP 注解与配置文件 示意图
<!-- 以add开头的方法 -->
expression="execution(* add*(..))"
<!-- com.java包下所有类所有的方法 -->
expression="execution(* com.java.*.add*(..))"
可以采用Advice中添加一个JoinPoint参数获得调用参数
package com.java;
import org.aspectj.lang.JoinPoint;
public class Check {
private void check(JoinPoint joinPoint){
//获取参数列表的值
for(int i=0;i<joinPoint.getArgs().length;i++){
System.out.println(joinPoint.getArgs()[i]);
}
//获取调用的方法
System.out.println(joinPoint.getSignature().getName());
System.out.println("例行检查");
}
}
JDK动态代理与CGLIB代理的区别?
- JDK动态代理对实现了接口类进行代理 (spring默认)
- CGLIB代理可以对类进行代理,主要对指定的类生成一个子类,因为是继承(类不能被final声明)
<!-- 1、导入CGLIB包 -->
<!-- 2、强制使用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
Spring与Hibernate集成声明式事务(简单示例)
User.java
public class User {
private int id;
private String name;
//Setter Getter 省略
}
User.hbm.xml
<hibernate-mapping>
<class name="com.domain.User">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
Log.java
public class Log {
private int id;
//日志类别,
private String type;
private String detail;
private Date date;
//Setter Getter 省略
}
Log.hbm.xml
<hibernate-mapping>
<class name="com.domain.Log">
<id name="id">
<generator class="native"/>
</id>
<property name="type"/>
<property name="detail"/>
<property name="date"/>
</class>
</hibernate-mapping>
Test.java
public class Test {
public static void main(String[] args){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = (UserManager)factory.getBean("userManager");
User user = new User();
user.setName("大龙");
try {
userManager.addUser(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
UserManager.java
public interface UserManager {
public void addUser(User user) throws Exception;
}
LogManager.java
public interface LogManager {
public void addLog(Log log);
}
UserManagerImpl.java
public class UserManagerImpl extends HibernateDaoSupport implements UserManager{
private LogManager logManager;
public void setLogManager(LogManager logManager) {
this.logManager = logManager;
}
@Override
public void addUser(User user) throws Exception {
// this.getHibernateTemplate().save(user);
this.getSession().save(user);
Log log = new Log();
log.setType("操作日志");
log.setDate(new Date());
log.setDetail("我妹干坏事");
logManager.addLog(log);
}
}
LogManagerImpl.java
public class LogManagerImpl extends HibernateDaoSupport implements LogManager{
@Override
public void addLog(Log log) {
this.getSession().save(log);
System.out.println("你的操作已记录");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="userManager" class="com.impl.UserManagerImpl">
<property name="logManager" ref="logManager"></property>
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="logManager" class="com.impl.LogManagerImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- Hibernate模板配置 -->
<!-- 创建sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transationManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置哪些方法使用事务-->
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution(* com.manager.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
<!-- 配置事务传播特性 查询只读提升效率 -->
<tx:advice id="txAdvice" transaction-manager="transationManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/domain/User.hbm.xml"/>
<mapping resource="com/domain/Log.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Spring其他知识点:
Spring默认在创建工厂的时候,将配置文件中所有的对象实例化并且进行注入 但也可使用懒加载属性
lazy-init="true"
//工厂模式 一样使用
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring bean的作用域
scope取值
singleton:默认 单例模式
prototype:多例模式 每次取出对象都不一样
根据名字自动装配、根据类型自动装配
default-autowire="byName" //查找配置文件id
default-autowire="byType" //查找配置文件class
Spring sessionFactory 的配置
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="file:src/hibernate.cfg.xml">
</property>
</bean>