diff --git a/src/asciidoc/core-aop.adoc b/src/asciidoc/core-aop.adoc index 5fc62fb460..57dffd371a 100644 --- a/src/asciidoc/core-aop.adoc +++ b/src/asciidoc/core-aop.adoc @@ -438,7 +438,7 @@ be &&'ed, ||'ed, and ! (negated) too. ==== Please note that the '++bean++' PCD is __only__ supported in Spring AOP - and __not__ in native AspectJ weaving. It is a Spring-specific extension to the standard PCDs that -AspectJ defines. +AspectJ defines and therefore not available for aspects declared in the `@Aspect` model. The '++bean++' PCD operates at the __instance__ level (building on the Spring bean name concept) rather than at the type level only (which is what weaving-based AOP is limited @@ -1991,7 +1991,7 @@ proceed with the method call: the presence of this parameter is an indication th public class SimpleProfiler { public Object profile(ProceedingJoinPoint call, String name, int age) throws Throwable { - StopWatch clock = new StopWatch("Profiling for ''" + name + "'' and ''" + age + "''"); + StopWatch clock = new StopWatch("Profiling for '" + name + "' and '" + age + "'"); try { clock.start(call.toShortString()); return call.proceed(); @@ -2884,10 +2884,9 @@ A `@Transactional` annotation on a class specifies the default transaction seman the execution of any __public__ operation in the class. A `@Transactional` annotation on a method within the class overrides the default -transaction semantics given by the class annotation (if present). Methods with `public`, -`protected`, and default visibility may all be annotated. Annotating `protected` and -default visibility methods directly is the only way to get transaction demarcation for -the execution of such methods. +transaction semantics given by the class annotation (if present). Methods of any +visibility may be annotated, including private methods. Annotating non-public methods +directly is the only way to get transaction demarcation for the execution of such methods. [TIP] ==== diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc index 2214a26d6b..3a78701b82 100644 --- a/src/asciidoc/core-beans.adoc +++ b/src/asciidoc/core-beans.adoc @@ -437,6 +437,16 @@ you are using Spring AOP it helps a lot when applying advice to a set of beans r by name. **** +[NOTE] +==== +With component scanning in the classpath, Spring generates bean names for unnamed +components, following the rules above: essentially, taking the simple class name +and turning its initial character to lower-case. However, in the (unusual) special +case when there is more than one character and both the first and second characters +are upper case, the original casing gets preserved. These are the same rules as +defined by `java.beans.Introspector.decapitalize` (which Spring is using here). +==== + [[beans-beanname-alias]] ==== Aliasing a bean outside the bean definition @@ -1719,7 +1729,7 @@ then nested `constructor-arg` elements. Let's review the examples from <> with the `c:` namespace: -[source,java,indent=0] +[source,xml,indent=0] [subs="verbatim,quotes"] ---- @@ -2561,7 +2571,7 @@ The Spring container creates a new instance of the `AppPreferences` bean by usin `appPreferences` bean is scoped at the `ServletContext` level, stored as a regular `ServletContext` attribute. This is somewhat similar to a Spring singleton bean but differs in two important ways: It is a singleton per `ServletContext`, not per Spring -'ApplicationContext' (or which there may be several in any given web application), +'ApplicationContext' (for which there may be several in any given web application), and it is actually exposed and therefore visible as a `ServletContext` attribute. @@ -3707,7 +3717,7 @@ Find below the custom `BeanPostProcessor` implementation class definition: public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - System.out.println("Bean ''" + beanName + "'' created : " + bean.toString()); + System.out.println("Bean '" + beanName + "' created : " + bean.toString()); return bean; } @@ -5414,7 +5424,7 @@ resolving expression text. The `@Bean` methods in a Spring component are processed differently than their counterparts inside a Spring `@Configuration` class. The difference is that `@Component` classes are not enhanced with CGLIB to intercept the invocation of methods and fields. -CGLIB proxying is the means by which invoking methods or fields within `@Bean` methods +CGLIB proxying is the means by which invoking methods or fields within `@Bean` methods in `@Configuration` classes creates bean metadata references to collaborating objects; such methods are __not__ invoked with normal Java semantics but rather go through the container in order to provide the usual lifecycle management and proxying of Spring @@ -5798,8 +5808,8 @@ It is very common to use `@Component` without specifying a name for the componen } ---- -When using `@Named`, it is possible to use -component-scanning in the exact same way as when using Spring annotations: +When using `@Named`, it is possible to use component scanning in the exact same way +as when using Spring annotations: [source,java,indent=0] [subs="verbatim,quotes"] @@ -5811,6 +5821,12 @@ component-scanning in the exact same way as when using Spring annotations: } ---- +[NOTE] +==== +In contrast to `@Component`, the JSR-330 `@Named` annotation is not composable. +Please use Spring's stereotype model for building custom component annotations. +==== + [[beans-standard-annotations-limitations]] @@ -7460,7 +7476,7 @@ hierarchy of property sources. To explain fully, consider the following: ApplicationContext ctx = new GenericApplicationContext(); Environment env = ctx.getEnvironment(); boolean containsFoo = env.containsProperty("foo"); -System.out.println("Does my environment contain the ''foo'' property? " + containsFoo); +System.out.println("Does my environment contain the 'foo' property? " + containsFoo); ---- In the snippet above, we see a high-level way of asking Spring whether the `foo` property is diff --git a/src/asciidoc/integration.adoc b/src/asciidoc/integration.adoc index febfb656b7..532852bcee 100644 --- a/src/asciidoc/integration.adoc +++ b/src/asciidoc/integration.adoc @@ -6001,7 +6001,7 @@ along with an inline image. helper.setTo("test@host.com"); // use the true flag to indicate the text included is HTML - helper.setText("", true); + helper.setText("", true); // let's include the infamous windows Sample file (this time copied to c:/) FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg")); @@ -6492,7 +6492,7 @@ reference is provided for managing those methods annotated with `@Scheduled`. [[scheduling-annotation-support-scheduled]] ==== The @Scheduled Annotation -The @Scheduled annotation can be added to a method along with trigger metadata. For +The `@Scheduled` annotation can be added to a method along with trigger metadata. For example, the following method would be invoked every 5 seconds with a fixed delay, meaning that the period will be measured from the completion time of each preceding invocation. @@ -6556,13 +6556,13 @@ Context, then those would typically have been provided through dependency inject [NOTE] ==== -Make sure that you are not initializing multiple instances of the same @Scheduled +Make sure that you are not initializing multiple instances of the same `@Scheduled` annotation class at runtime, unless you do want to schedule callbacks to each such -instance. Related to this, make sure that you do not use @Configurable on bean classes -which are annotated with @Scheduled and registered as regular Spring beans with the -container: You would get double initialization otherwise, once through the container and -once through the @Configurable aspect, with the consequence of each @Scheduled method -being invoked twice. +instance. Related to this, make sure that you do not use `@Configurable` on bean +classes which are annotated with `@Scheduled` and registered as regular Spring beans +with the container: You would get double initialization otherwise, once through the +container and once through the `@Configurable` aspect, with the consequence of each +`@Scheduled` method being invoked twice. ==== @@ -6613,8 +6613,8 @@ asynchronous execution so that the caller can perform other tasks prior to calli ---- `@Async` can not be used in conjunction with lifecycle callbacks such as -`@PostConstruct`. To asynchronously initialize Spring beans you currently have to use a -separate initializing Spring bean that invokes the `@Async` annotated method on the +`@PostConstruct`. To asynchronously initialize Spring beans you currently have to use +a separate initializing Spring bean that invokes the `@Async` annotated method on the target then. [source,java,indent=0] @@ -6629,7 +6629,7 @@ target then. } - public class SampleBeanInititalizer { + public class SampleBeanInitializer { private final SampleBean bean; @@ -6645,6 +6645,14 @@ target then. } ---- +[NOTE] +==== +There is no direct XML equivalent for `@Async` since such methods should be designed +for asynchronous execution in the first place, not externally re-declared to be async. +However, you may manually set up Spring's `AsyncExecutionInterceptor` with Spring AOP, +in combination with a custom pointcut. +==== + [[scheduling-annotation-support-qualification]] @@ -7360,7 +7368,7 @@ message is surrounded by quotes. Below are the changes that I (the author) make public String getMessage() { // change the implementation to surround the message in quotes - return "''" + this.message + "''" + return "'" + this.message + "'" } public void setMessage(String message) { @@ -7767,7 +7775,7 @@ will want to do with this callback, and you can see an example of doing that bel DelegatingMetaClass metaClass = new DelegatingMetaClass(goo.getMetaClass()) { public Object invokeMethod(Object object, String methodName, Object[] arguments) { - System.out.println("Invoking ''" + methodName + "''."); + System.out.println("Invoking '" + methodName + "'."); return super.invokeMethod(object, methodName, arguments); } }; @@ -8814,7 +8822,7 @@ up its declaration at runtime and understands its meaning. Note that as mentione === JCache (JSR-107) annotations Since the Spring Framework 4.1, the caching abstraction fully supports the JCache -standard annotations: these are `@CacheResult`, `@CacheEvict`, `@CacheRemove` and +standard annotations: these are `@CacheResult`, `@CachePut`, `@CacheRemove` and `@CacheRemoveAll` as well as the `@CacheDefaults`, `@CacheKey` and `@CacheValue` companions. These annotations can be used right the way without migrating your cache store to JSR-107: the internal implementation uses Spring's caching abstraction @@ -8996,7 +9004,7 @@ we did in the example above by defining the target cache through the `cache:defi [[cache-store-configuration]] === Configuring the cache storage -Out of the box, the cache abstraction provides several storages integration. To use +Out of the box, the cache abstraction provides several storage integration. To use them, one needs to simply declare an appropriate `CacheManager` - an entity that controls and manages ++Cache++s and can be used to retrieve these for storage.