001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.aop.framework;
018
019import java.io.Serializable;
020
021import org.springframework.util.Assert;
022
023/**
024 * Convenience superclass for configuration used in creating proxies,
025 * to ensure that all proxy creators have consistent properties.
026 *
027 * @author Rod Johnson
028 * @author Juergen Hoeller
029 * @see AdvisedSupport
030 */
031public class ProxyConfig implements Serializable {
032
033        /** use serialVersionUID from Spring 1.2 for interoperability */
034        private static final long serialVersionUID = -8409359707199703185L;
035
036
037        private boolean proxyTargetClass = false;
038
039        private boolean optimize = false;
040
041        boolean opaque = false;
042
043        boolean exposeProxy = false;
044
045        private boolean frozen = false;
046
047
048        /**
049         * Set whether to proxy the target class directly, instead of just proxying
050         * specific interfaces. Default is "false".
051         * <p>Set this to "true" to force proxying for the TargetSource's exposed
052         * target class. If that target class is an interface, a JDK proxy will be
053         * created for the given interface. If that target class is any other class,
054         * a CGLIB proxy will be created for the given class.
055         * <p>Note: Depending on the configuration of the concrete proxy factory,
056         * the proxy-target-class behavior will also be applied if no interfaces
057         * have been specified (and no interface autodetection is activated).
058         * @see org.springframework.aop.TargetSource#getTargetClass()
059         */
060        public void setProxyTargetClass(boolean proxyTargetClass) {
061                this.proxyTargetClass = proxyTargetClass;
062        }
063
064        /**
065         * Return whether to proxy the target class directly as well as any interfaces.
066         */
067        public boolean isProxyTargetClass() {
068                return this.proxyTargetClass;
069        }
070
071        /**
072         * Set whether proxies should perform aggressive optimizations.
073         * The exact meaning of "aggressive optimizations" will differ
074         * between proxies, but there is usually some tradeoff.
075         * Default is "false".
076         * <p>For example, optimization will usually mean that advice changes won't
077         * take effect after a proxy has been created. For this reason, optimization
078         * is disabled by default. An optimize value of "true" may be ignored
079         * if other settings preclude optimization: for example, if "exposeProxy"
080         * is set to "true" and that's not compatible with the optimization.
081         */
082        public void setOptimize(boolean optimize) {
083                this.optimize = optimize;
084        }
085
086        /**
087         * Return whether proxies should perform aggressive optimizations.
088         */
089        public boolean isOptimize() {
090                return this.optimize;
091        }
092
093        /**
094         * Set whether proxies created by this configuration should be prevented
095         * from being cast to {@link Advised} to query proxy status.
096         * <p>Default is "false", meaning that any AOP proxy can be cast to
097         * {@link Advised}.
098         */
099        public void setOpaque(boolean opaque) {
100                this.opaque = opaque;
101        }
102
103        /**
104         * Return whether proxies created by this configuration should be
105         * prevented from being cast to {@link Advised}.
106         */
107        public boolean isOpaque() {
108                return this.opaque;
109        }
110
111        /**
112         * Set whether the proxy should be exposed by the AOP framework as a
113         * ThreadLocal for retrieval via the AopContext class. This is useful
114         * if an advised object needs to call another advised method on itself.
115         * (If it uses {@code this}, the invocation will not be advised).
116         * <p>Default is "false", in order to avoid unnecessary extra interception.
117         * This means that no guarantees are provided that AopContext access will
118         * work consistently within any method of the advised object.
119         */
120        public void setExposeProxy(boolean exposeProxy) {
121                this.exposeProxy = exposeProxy;
122        }
123
124        /**
125         * Return whether the AOP proxy will expose the AOP proxy for
126         * each invocation.
127         */
128        public boolean isExposeProxy() {
129                return this.exposeProxy;
130        }
131
132        /**
133         * Set whether this config should be frozen.
134         * <p>When a config is frozen, no advice changes can be made. This is
135         * useful for optimization, and useful when we don't want callers to
136         * be able to manipulate configuration after casting to Advised.
137         */
138        public void setFrozen(boolean frozen) {
139                this.frozen = frozen;
140        }
141
142        /**
143         * Return whether the config is frozen, and no advice changes can be made.
144         */
145        public boolean isFrozen() {
146                return this.frozen;
147        }
148
149
150        /**
151         * Copy configuration from the other config object.
152         * @param other object to copy configuration from
153         */
154        public void copyFrom(ProxyConfig other) {
155                Assert.notNull(other, "Other ProxyConfig object must not be null");
156                this.proxyTargetClass = other.proxyTargetClass;
157                this.optimize = other.optimize;
158                this.exposeProxy = other.exposeProxy;
159                this.frozen = other.frozen;
160                this.opaque = other.opaque;
161        }
162
163        @Override
164        public String toString() {
165                StringBuilder sb = new StringBuilder();
166                sb.append("proxyTargetClass=").append(this.proxyTargetClass).append("; ");
167                sb.append("optimize=").append(this.optimize).append("; ");
168                sb.append("opaque=").append(this.opaque).append("; ");
169                sb.append("exposeProxy=").append(this.exposeProxy).append("; ");
170                sb.append("frozen=").append(this.frozen);
171                return sb.toString();
172        }
173
174}