标签:
学习示例代码,包含本篇介绍的Spring常用操作示例和所有所需jar文件下载地址:http://download.csdn.net/detail/daijin888888/9556697
类名 对象名 = (类名) ac.getBean("标识符");
示例:
public class JdbcCostDao implements CostDao {
public JdbcCostDao() {
System.out.println("JdbcCostDao构造");
}
public void init() {
System.out.println("初始化JdbcCostDao");
}
@Override
public void save() {
System.out.println("采用jdbc保存对象");
}
@Override
public void delete() {
String s = null;
s.length();// 模拟异常
System.out.println("采用jdbc删除对象");
}
public void destory() {
System.out.println("释放资源");
}
}<bean id="jdbcCostDao" scope="singleton" init-method="init" destroy-method="destory" class="com.test.dao.JdbcCostDao"></bean>
// 测试回收
@Test
public void test2() {
// 实例化Spring容器对象
String conf = "/applicationContext.xml";
AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf);
// 从容器中获取Bean
CostDao costDao = (CostDao) ac.getBean("jdbcCostDao");
costDao.save();
ac.close();// 释放容器对象-->触发释放Bean对象-->触发destory-method方法
}运行结果:采用jdbc保存对象 释放资源*a.控制Bean对象创建模式
</property>
</bean>
示例:
public class AddCostAction {
// 属性(略)
// 定义注入属性
private CostDao costDao;
public CostDao getCostDao() {
return costDao;
}
// Spring容器会自动调用该方法注入costDao
public void setCostDao(CostDao costDao) {
this.costDao = costDao;
}
public String exeucte() {
System.out.println("开始处理资费添加请求");
// CostDao costDao = new JdbcCostDao();//采用注入的方式替代直接生成,以此解耦
costDao.save();
return "success";
}
}applicationContext.xml中配置:<bean id="hibernateCostDAO" class="com.test.dao.HibernateCostDAO"></bean> <bean id="addCostAction" scope="prototype" class="com.test.action.AddCostAction"> <!-- setter注入配置,将hibernateCostDAO对象给action的setCostDao方法传入 --> <property name="costDao" ref="hibernateCostDAO"></property> </bean>c.IoC使用方法(构造方式注入实现)
</bean>
示例:
public class DeleteCostAction {
private CostDao costDao;
public DeleteCostAction() {
}
public DeleteCostAction(CostDao costDao) {
this.costDao = costDao;
}
public String exeucte() {
System.out.println("删除资费请求的处理");
costDao.delete();
return "success";
}
}applicationContext.xml中配置:<bean id="jdbcCostDao" scope="singleton" init-method="init" destroy-method="destory" class="com.test.dao.JdbcCostDao"></bean> <bean id="deleteCostAction" class="com.test.action.DeleteCostAction"> <!-- 构造参数注入配置,将jdbcCostDao对象给action的构造方法的第一个参数传入 --> <constructor-arg index="0" ref="jdbcCostDao"></constructor-arg> </bean>d.各种类型数据的注入
示例:
<bean id="messagebean" class="com.test.action.MessageBean"> <property name="dir" value="D:\\images\"></property> <property name="size" value="10240"></property> <!-- 注入List --> <property name="types"> <list> <value>jpg</value> <value>jpeg</value> <value>gif</value> </list> </property> <!-- 注入Set --> <property name="cites"> <set> <value>北京</value> <value>上海</value> <value>广州</value> </set> </property> <!-- 注入Map --> <property name="books"> <map> <entry key="1001" value="Java语言基础"></entry> <entry key="1002" value="JavaWeb基础"></entry> <entry key="1003" value="SSH框架技术"></entry> </map> </property> <!-- 注入Properties --> <property name="dbParams"> <props> <prop key="username">root</prop> <prop key="password">123456</prop> <prop key="driverClassName">com.mysql.jdbc.Driver</prop> </props> </property> </bean>对应接收注入的Java文件:
/**
* @Description:测试注入数据类别
*
*/
public class MessageBean {
private String dir;
private int size;
private List<String> types;
private Set<String> cites;
private Map<String, String> books;
private Properties dbParams;
public List<String> getTypes() {
return types;
}
public void setTypes(List<String> types) {
this.types = types;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Set<String> getCites() {
return cites;
}
public void setCites(Set<String> cites) {
this.cites = cites;
}
public Map<String, String> getBooks() {
return books;
}
public void setBooks(Map<String, String> books) {
this.books = books;
}
public Properties getDbParams() {
return dbParams;
}
public void setDbParams(Properties dbParams) {
this.dbParams = dbParams;
}
public void show() {
System.out.println("--显示注入参数--");
System.out.println("dir:" + dir);
System.out.println("size:" + size);
System.out.println("允许上传的类型如下:");
for (String s : types) {
System.out.println(s);
}
System.out.println("城市信息:");
for (String s : cites) {
System.out.println(s);
}
System.out.println("图书信息:");
Set<Entry<String, String>> book = books.entrySet();
for (Entry en : book) {
System.out.println(en.getKey() + ":" + en.getValue());
}
System.out.println("显示数据库连接参数:");
Set keys = dbParams.keySet();
for (Object key : keys) {
System.out
.println(key + "=" + dbParams.getProperty(key.toString()));
}
}
}
测试程序:
public class TestMessageBean {
@Test
public void test1() {
String conf = "/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
MessageBean bean = (MessageBean) ac.getBean("messagebean");
bean.show();
}
}测试结果:--显示注入参数-- dir:D:\\imagessize:10240 允许上传的类型如下: jpg jpeg gif 城市信息: 北京 上海 广州 图书信息: 1001:Java语言基础 1002:JavaWeb基础 1003:SSH框架技术 显示数据库连接参数: password=123456 driverClassName=com.mysql.jdbc.Driver username=root
方面代码:
public class OptLogger {
/**
* @param pjp
* 连接点(需用环绕通知切入)
* @throws Throwable
*/
public Object log(ProceedingJoinPoint pjp) throws Throwable {
Object obj = pjp.proceed();// 执行目标组件方法处理
// 获取当前请求要执行的Action目标组件类型
String className = pjp.getTarget().getClass().getName();
// 获取当前请求要执行的方法名
String methodName = pjp.getSignature().getName();
// 根据类名和方法名形成key
String key = className + "." + methodName;
// 解析opt.properties,根据key获取操作动作描述
String optName = PropertiesUtil.getProperty(key);
System.out.println("XXX在" + new Date() + "时间做了" + optName + "操作");
return obj;// 将proceed目标方法结果返回
}
}
PropertiesUtil用于读取配置文件,可将特定操作(类+方法转换成中文描述)
<pre name="code" class="java">public class PropertiesUtil {
private static Properties props = new Properties();
static{
try{
InputStream inStream = PropertiesUtil.class
.getClassLoader().getResourceAsStream(
"opt.properties");
props.load(inStream);
}catch(Exception ex){
ex.printStackTrace();
}
}
public static String getProperty(String key){
String val = props.getProperty(key);
return val;
}
}opt.properties:(使用native2ascii tool工具将中文转码)<!-- AOP配置 --> <bean id="optLogger" class="com.test.aspect.OptLogger"> <aop:config> <!-- 指定切入点 --> <aop:pointcut id="actionPointcut" expression="within(com.test.action.*)" /> <!-- 将id=optLogger的Bean指定为方面组件 --> <aop:aspect id="optLoggerAspect" ref="optLogger"> <!-- 指定通知,控制方面和目标组件作用时机 --> <aop:around pointcut-ref="actionPointcut" method="log" /> </aop:aspect> </aop:config>
(示例:如6中用Log4j记录程序异常信息并保存下来)
--在src下添加log4j.properties配置文件
如:
log4j.rootLogger=error,myconsole,myfile log4j.appender.myfile=org.apache.log4j.FileAppender log4j.appender.myfile.File=D:\\log4j.html log4j.appender.myfile.layout=org.apache.log4j.HTMLLayout log4j.appender.myconsole=org.apache.log4j.ConsoleAppender log4j.appender.myconsole.layout=org.apache.log4j.SimpleLayout
/**
* @Description:异常记录方面组件
*/
public class ExceptionLogger {
// 获取日志器
private static Logger logger = Logger.getLogger(ExceptionLogger.class);
// ex就是目标方法抛出的异常对象
public void logException(Exception ex) {
// System.out.println("将异常写入文件" + ex);
// 采用Log4j日志工具记录异常信息
logger.error(ex);
logger.error(ex.getStackTrace()[0]);
}
}<!-- AOP配置 --> <bean id="exceptionLogger" class="com.test.aspect.ExceptionLogger"> </bean> <!-- 指定切入点 --> <aop:pointcut id="daoPointcut" expression="within(com.test.dao..*)" /> <aop:config> <!-- 将id=exceptionLogger的Bean指定为方面组件 --> <!-- trowing指定logException方法的参数名,用于接收目标方法抛出的异常对象 --> <aop:aspect id="exceptionLoggerAspect" ref="exceptionLogger"> <aop:after-throwing pointcut-ref="daoPointcut" method="logException" throwing="ex" /> </aop:aspect> </aop:config>在配置文件指定的地方生产文件如下:
D:\\log4j.htmlLog session start time Wed Jun 22 17:00:13 CST 2016
| Time | Thread | Level | Category | Message |
|---|---|---|---|---|
| 0 | main | ERROR | com.test.aspect.ExceptionLogger | java.lang.NullPointerException |
| 1 | main | ERROR | com.test.aspect.ExceptionLogger | com.test.dao.JdbcCostDao.delete(JdbcCostDao.java:22) |
| Time | Thread | Level | Category | Message |
|---|---|---|---|---|
| 0 | main | ERROR | com.test.aspect.ExceptionLogger | java.lang.NullPointerException |
| 3 | main | ERROR | com.test.aspect.ExceptionLogger | com.test.dao.JdbcCostDao.delete(JdbcCostDao.java:22) |
1)什么是注解
注解技术是JDK5.0开始提供的。
它的标记格式为"@名称",它可以定义在类前、方法前、成员变量前。
2)使用注解的好处
现在的框架都提供了注解配置,利用注解技术去简化或替代原有的XML配置。
3)Spring的组件扫描技术
Spring可以自动扫描指定包下的Class组件,如果发现类定义前面有以下几个标记
@Controller(Action组件应用)
@Service(Service业务组件应用)
@Repository(DAO组件应用)
@Component(其他组件应用)
就会将该组件扫描到Spring容器,由容器负责管理和对象的创建,等价于XML中<bean>定义。
使用方法:
--在applicationContext.xml中开启组件扫描功能 <context:component-scan base-package="指定包路径"/>
--在Action或DAO等组件类定义前使用上述标记。默认用类名首字母小写当id,也可以采用@Repository("指定id")格式
其他<bean>属性注解标记:
@Scope("prototype"或"singleton")等价于scope属性
@PreDestory等价于destory-method属性
@PostConstruct等价于init-method属性
4)注入的注解
@Resource
@Autowired
上面两种标记都可以实现类型匹配注入,但是如果遇到多个匹配对象时,会发生异常。这时需要指定注入哪个id的Bean
@Resource(name="指定id")
@Autowired()
@Qualifier("指定id")
上面标记可以写在变量定义前或set方法前。写在变量定义前时,set可省略。
5)AOP注解配置
使用方法:
--在applicationContext.xml中开启AOP的注解配置<aop:aspectj-autoproxy/>
--在方面组件中类定义前使用下面标记
@Component //将Bean扫描到容器
@Aspect //将Bean升级为方面组件
--在方面组件中定义一个空方法,利用@Point标记定义切入表达式
@Pointcut("切入表达式")
public void mypoint(){}
--在方面组件处理方法上,使用下面通知标记
@Before 前置通知标记
@Around 环绕通知标记
@AfterReturning 后置通知标记
@AfterThrowing 异常通知标记
@After 最终通知标记
Spring基础、IOC(控制反转)、AOP(面向切面编程)、Log4j、注解配置
标签:
原文地址:http://blog.csdn.net/daijin888888/article/details/51735291