spring配置注解、切面、Tomcat日志
使用注解获取properties中参数
spring配置:<util:properties id="GCoin_service" location="classpath:props/gcoin-service.properties" />
@Value("#{GCoin_service['pushRealNameURL']}")
private String pushRealNameURL;
注解自动扫描
<aop:aspectj-autoproxy proxy-target-class="true"/> <mvc:annotation-driven /> <mvc:default-servlet-handler />
<context:annotation-config/> <context:component-scan base-package="cn.com.gome" />
<context:annotation-config> 是用于激活那些已经在spring容器里注册过的bean(无论是通过xml的方式还是通过package sanning的方式)上面的注解。
<context:component-scan>除了具有<context:annotation-config>的功能之外,<context:component-scan>还可以在指定的package下扫描以及注册javabean
<mvc:annotation-driven>会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的,并且提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持读写XML的支持(JAXB)和读写JSON的支持(默认Jackson)等功能
<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面
<mvc:default-servlet-handler />会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去
声明bean:
org.springframework.stereotype.Component
@Component 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
org.springframework.stereotype.Service
@Service 用于标注业务层组件
注入bean:
javax.annotation.Resource
@Resource 默认是按照byName方式注入的 @Resource(name="xxx")
org.springframework.beans.factory.annotation.Autowired
@Autowired 默认先按byType,如果发现找到多个bean,则,又按照byName方式比对 @Autowired也可以手动指定按照byName方式注入,使用@Qualifier标签
事物声明:
@Service 对类修饰
@Transactional 对类修饰
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)//事务处理
public ResultEnum exec(CashierParametersVo vo) throws GomeFinanceException {......//方法必须有异常抛出
手动加载配置文件,获取bean
context = new ClassPathXmlApplicationContext( new String[] {"classpath:spring.xml" });
MyService my;
//my = context.getBean(MyService.class);
my = ( MyService)context.getBean("myServiceImpl");//MyServiceImpl 实现 MyService
spring Bean生命周期
1.Bean的作用域可以通过Bean标签的scope属性进行设置,Bean的作用域包括:
默认情况下scope="singleton",那么该Bean是单例,任何人获取该Bean实例的都为同一个实例;
scope="prototype",任何一个实例都是新的实例;
scope="request",在WEB应用程序中,每一个实例的作用域都为request范围;
scope="session",在WEB应用程序中,每一个实例的作用域都为session范围;
注意:在默认情况下,Bean实例在被Spring容器初始化的时候,就会被实例化,默认调用无参数的构造方法。在其它情况下,Bean将会在获取实例的时候才会被实例化。
2.Bean可以通过指定属性init-method指定初始化后执行的方法,以及通过指定属性destroy-method销毁时执行的方法。
语法:<bean .... destroy-method="销毁时调用的方法名" init-method="初始化后执行的方法名"/>
***********************************************************************日志输出问题*******************************************************************************
注解aop
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 使用注解时要开启注解扫描 要扫描的包 -->
<context:component-scan base-package="cn.itcast.e_aop_anno"></context:component-scan>
<!-- 开启aop注解方式 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
@Component //加入IOC容器
@Aspect // 指定当前类为切面类
public class Aop {
// 指定切入点表达式: 拦截哪些方法; 即为哪些类生成代理对象
//解释@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
//@Pointcut("execution(* 切入点表达式固定写法, cn.itcast.e_aop_anno表示包.类名(可以用*表示包下所有的类).方法名(可以用*表示类下所有的方法)(..)表示参数可以用..
@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
public void pointCut_(){
}
//@Before("execution(* cn.itcast.e_aop_anno.*.*(..))")每个方法需要写相同的引用,所以将相同的部分抽取到一个空的方法中pointCut_(),
// 前置通知 : 在执行目标方法之前执行
@Before("pointCut_()")
public void begin(){
System.out.println("开始事务/异常");
}
// 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
@After("pointCut_()")
public void after(){
System.out.println("提交事务/关闭");
}
// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
@AfterReturning("pointCut_()")
public void afterReturning() {
System.out.println("afterReturning()");
}
// 异常通知: 当目标方法执行异常时候执行此关注点代码
@AfterThrowing("pointCut_()")
public void afterThrowing(){
System.out.println("afterThrowing()");
}
// 环绕通知:环绕目标方式执行
@Around("pointCut_()")
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前....");
pjp.proceed(); // 执行目标方法
System.out.println("环绕后....");
}
}
// 接口
public interface IUserDao {
void save();
}
@Component // 加入容器
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----核心业务:保存!!!------");
}
}
没有实现接口
@Component // 加入容器
@Scope("prototype")
public class OrderDao{
public void save() {
System.out.println("-----核心业务:保存!!!------");
}
}
public class App {
ApplicationContext ac =
new ClassPathXmlApplicationContext("cn/itcast/e_aop_anno/bean.xml");
// 目标对象有实现接口,spring会自动选择“JDK代理”
@Test
public void testApp() {
IUserDao userDao = (IUserDao) ac.getBean("userDao");
System.out.println(userDao.getClass());//$Proxy001
userDao.save();
}
// 目标对象没有实现接口, spring会用“cglib代理”
@Test
public void testCglib() {
OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
System.out.println(orderDao.getClass());
orderDao.save();
}
***********************************************************************windows tomcat日志输出问题*******************************************************************************
把控制台的信息输出到%CATALINA_BASE%\logs\catalina.out里:
1、打开bin下面的startup.bat文件,把call "%EXECUTABLE%" start %CMD_LINE_ARGS%
改为call "%EXECUTABLE%" run %CMD_LINE_ARGS% 。
注:上面这样设置之后,运行tomcat后,就不会出来tomcat运行窗口了。
2、打开bin下面的catalina.bat文件,会发现共有4处 %ACTION% ,在后面分别加上
>> %CATALINA_HOME%\logs\catalina.out 。
注:windows中反斜杠和linux永远是反的,windows喜欢搞另类
重启tomcat,就会发现在logs文件夹下出现了catalina.out文件,把原来控制台的信息全写进去了。
但输出的这个catalina.out文件,是一直增长的,也就是文件会越来越大。
优化
按照上面的修改,tomcat所有的日志都会写入到logs/catalina.out文件内,如果想要按天来生成日志文件,可以在%ACTION%后添加 >> %CATALINA_HOME%/logs/catalina.%date:~0,4%-%date:~5,2%-%date:~8,2%.out,生成的格式为catalina.yyyy-mm-dd.out(yyyy代表4位年份,mm代表为2位月份,dd代表两位日期)
***********************************************************************linux tomcat日志输出问题*******************************************************************************
由于Tomcat在默认情况下会将没有经过配置的web应用所产生的日志输出已经其本身的日志内容都输出到这个文件中,那么随着时间的推移,这个文件的尺寸将会越来越大,当需要检查日志内容时间会导致文件难以打开,而且同时tomcat依旧在不断的向文件中输入内容,这也会降低tomcat的性能。下面利用一个工具来将tomcat产生的catalina.out文件根据日期来分割,将每天产生的日志存放在一个独立的文件中,这样单个log文件就不会太大,而且过期的日志文件可以根据情况在不需要的时间删除掉,或者备份到其他地方。
这里需要一个工具叫cronolog,这个工具的作用是将标准输出中的内容重定向到文件,但是可以根据规则对文件命名,这样我们就可以将标准输出中的内容重定向到根据日期命名的log文件中了,然后只要将tomcat的日志输出指向标准输出就可以搞定问题了。下面是具体配置步骤
一、获取与安装cronolog工具
1. 到这里(http://cronolog.org/download/index.html)下载最新版本,本文编写时的最新版本是1.6.2版本。
2. 将下载好的文件解压缩,tar xvzf cronolog.tar.gz
3. 切换到解压缩之后的cronolog目录中
4. 初始化和编译安装
./configure --prefix=/usr/local/cronolog (这里--prefix后面的路径是你希望该工具的安装目标路径)
./make
./make install
二、修改tomcat的启动文件(tomcat/bin/catalina.sh)
1. 找到文件中的如下内容(注意:有两处)
org.apache.catalina.startup.Bootstrap "$@" start /
>> "$CATALINA_BASE"/logs/catalina.out 2&1 &
将其修改成如下格式:
org.apache.catalina.startup.Bootstrap "$@" start 2>&1 /
| /usr/local/cronolog/sbin/cronolog "$CATALINA_BASE"/logs/catalina.%Y-%m-%d.out >> /dev/null &
2. 注释如下内容
#touch "CATALINA_BASE"/logs/catalina.out
然后重新启动tomcat就可以完成任务了

浙公网安备 33010602011771号