For reprinting, please indicate the source: http://www.cnblogs.com/Joanna-Yan/p/6567672.html
Project log is an indispensable part of project development and operation. With it, the system can be controlled as a whole and any problems can be traced.
If log processing is carried out with pure OOP idea, it will be found that every logical part will always be mixed with log processing code, which makes the design of pure OOP idea incompatible. If the type requirement of the log changes, the Java code needs to be modified in each logical unit. It will be a very tedious job if the requirements change again. Therefore, log processing should be a separate part of the project. We should not consider log processing when we are developing the system. AOP allows us to concentrate more on the business coding of the project without worrying about log issues.
First, we briefly introduce AOP (Aspect Oriented Programming):
AOP is the continuation of OOP, and it is a programming method of distracting attention. It encapsulates "concern" in the aspect, and achieves decoupling between caller and callee.
Decentralized attention: Separating common requirement functions from unrelated classes, and enabling multiple classes to share a single behavior, once the behavior changes, there is no need to modify many classes, just need to modify this behavior.
Object-oriented is a vertical structure, which can make the logical unit of the system clearer.
Face-oriented is a cross-cutting structure, which extracts the face of business logic layer. For example, the section completes a function, which is involved in every module. He cuts into the system like knife-cut tofu, and can complete the same control of the system.
Doubt: donet programs can run when deployed on servers, while Java programs have one more process, so they have to be deployed in containers to run? Why is J2EE unless it is a J2EE container and a J2EE application system?
Answer: The J2EE container is actually a common part of the separation of general application systems. These functions, such as transaction, security, database connection pool and so on, are separated into a general framework. The design and development of these functional mechanisms are difficult. At the same time, the stability and rapidity of operation are very important. It must be accumulated after a long period of debugging and operation experience, and gradually formed J2EE container service products such as Tomcat, JBoss, WebLogic and so on. Simply put, the container separated from J2EE is to take out most of the things that will be used in software, and gradually become a product after a long time.
From the two aspects of J2EE system, container and application system, we can see a decentralized idea.
Implementation process:
1. The jar package involved:
spring.jar
log4j-1.2.16.jar
aspectjrt.jar
aspectjweaver.jar
commons-logging.jar
2. Face-oriented Log classes:
import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class LogAspect { Logger logger=Logger.getLogger(LogAspect.class); String logStr=null; /** * Pre-notification: A notification executed before a join point, but this notification does not prevent the execution before the join point * @param jp Connection Point: An action in the execution of a program */ public void doBefore(JoinPoint jp){ logStr=jp.getTarget().getClass().getName()+"Class" +jp.getSignature().getName()+"Method Start Execution******Start******"; logger.info(logger); } /** * Circumscribed notification: A notification that surrounds a join point can complete custom behavior before and after method invocation, or can choose not to perform. * Similar to the doFilter method of Filter in the Servlet specification in the web. * @param pjp Connection Points in the Current Process * @return */ public Object doAround(ProceedingJoinPoint pjp){ long Time=System.currentTimeMillis(); Object result=null; try { result=pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); logStr="Method:"+pjp.getTarget().getClass()+"."+pjp.getSignature().getName()+"()"; logStr=logStr+"The error message is as follows:["+e+"]"; logger.info(logStr); } return result; } /** * after returning advise * @param jp */ public void doAfter(JoinPoint jp){ logStr=jp.getTarget().getClass().getName()+"Class" +jp.getSignature().getName()+"Method Execution End******End******"; logger.info(logStr); } }
3. Configure AOP-related logs in spring configuration file ApplicationContext.xml
<!--AOP Class log --> <bean id="logAspect" class="yan.joanna.log.LogAspect"></bean> <aop:config> <aop:aspect id="aspect" ref="logAspect"> <!--Which methods are logged and blocked here action Internal set get Method --> <aop:pointcut id="logService" expression="(execution(* yan.joanna.*.*.*(..)) ) and (!execution(* yan.joanna.action.*.set*(..)) ) and (!execution(* yan.joanna.action.*.get*(..)) )" /> <aop:before pointcut-ref="logService" method="doBefore"/> <aop:after pointcut-ref="logService" method="doAfter"/> <aop:around pointcut-ref="logService" method="doAround"/> </aop:aspect> </aop:config> <!-- To configure Action --> <bean id="UserAction" class="yan.joanna.action.UserAction" scope="prototype"> <property name="userDAO" ref="UserDAO"></property> <property name="maindeviceDAO" ref="MaindeviceDAO"></property> <property name="amountDAO" ref="AmountDAO"></property> <property name="deviceUsingDAO" ref="DeviceUsingDAO"></property> </bean>
4. Main configuration of log4j.properties file of log4j
log4j.rootLogger = info, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %p %d{yyyy-MM-dd HH:mm:ssS} || %c{1} || %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=d:/UTrainFileLib/logs/utrain.log
log4j.appender.R.Append=true
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] [%t] (%F\:%L) ->%m %n
log4j.appender.R.Threshold=INFO
log4j.appender.R.DatePattern='.'yyyy-MM-dd
5. In the early stages of development or operation, we may want to print some business logic, parameter values, etc., and control its printing level.
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class JYLog { private static final Log log = LogFactory.getLog(JYLog.class); public static void printLog(String msg){ if(log.isInfoEnabled()){ log.info(msg); } } public static void errorLog(String msg,Exception e){ log.error(msg, e); } public static void errorLog(String msg){ log.error(msg); } }
6. Printing of business log, login method in eg:UserAction:
/** * Sign in * @throws IOException */ public void login() throws IOException{ HttpServletRequest req=ServletActionContext.getRequest(); HttpServletResponse resp=ServletActionContext.getResponse(); req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); String tel=req.getParameter("tel"); JYLog.printLog("login()-Sign in-Timestamp-"+new Timestamp(System.currentTimeMillis())+ ";tel-"+tel); PrintWriter out=resp.getWriter(); JSONObject json=new JSONObject(); JSONObject dataJson=new JSONObject(); String message=""; int errorcode=0; if(!"".equals(tel)){ User user=userDAO.findByAccount(tel); if(user==null){ userDAO.save(new User(tel, new Timestamp(System.currentTimeMillis()),new Timestamp(System.currentTimeMillis()), 1)); user=userDAO.findByAccount(tel); amountDAO.save(new Amount(user, 100,0)); }else{ userDAO.updateLoginTime(user); } dataJson.put("id", user.getId()); dataJson.put("account", user.getAccount()); dataJson.put("type", user.getType()); message="Successful login"; errorcode=0; }else{ message="Illegal mobile phone number"; errorcode=10002; } json.put("data", dataJson); json.put("message", message); json.put("errorcode", errorcode); out.print(json); out.flush(); out.close(); JYLog.printLog("login()-Sign in-json-"+json.toString()); }
7. The content part of the log print file shows:
[yan.joanna.log.JYLog]-[INFO] [http-bio-59500-exec-56] (JYLog.java:11) ->login()-Sign in-Timestamp-2017-04-01 08:10:08.972;tel-15515123456 2017-04-01 08:10:08 [yan.joanna.log.LogAspect]-[INFO] [http-bio-59500-exec-56] (LogAspect.java:14) ->org.apache.log4j.Logger@10fb78e 2017-04-01 08:10:08 [yan.joanna.log.LogAspect]-[INFO] [http-bio-59500-exec-56] (LogAspect.java:34) ->yan.joanna.dao.UserDAO Class findByAccount Method Execution End******End****** 2017-04-01 08:10:08 [yan.joanna.log.LogAspect]-[INFO] [http-bio-59500-exec-56] (LogAspect.java:14) ->org.apache.log4j.Logger@10fb78e 2017-04-01 08:10:08 [yan.joanna.log.LogAspect]-[INFO] [http-bio-59500-exec-56] (LogAspect.java:34) ->yan.joanna.dao.UserDAO Class updateLoginTime Method Execution End******End****** 2017-04-01 08:10:09 [yan.joanna.log.JYLog]-[INFO] [http-bio-59500-exec-56] (JYLog.java:11) ->login()-Sign in-json-{"data":{"id":68,"account":"15515123456","type":1},"message":"Successful login","errorcode":0} 2017-04-01 08:10:09 [yan.joanna.log.LogAspect]-[INFO] [http-bio-59500-exec-56] (LogAspect.java:34) ->yan.joanna.action.UserAction Class login Method Execution End******End******